lrhorer
Posts: 47
Joined: Sun Feb 22, 2015 6:35 pm

javascript not working on RPi 3

Tue Nov 06, 2018 10:44 pm

I have a Raspberry Pi 3 running java 1.8.0_65, apache 2.4.25, and chromium-browser 60.0.3112.89 under Raspbian 9.4, and I am having some trouble with some javascript running from a CGI script. I have never in my life worked with javascript, and I am no expert with HTML or CGI, so am pretty lost, here.

I can bring up the following URL:

Code: Select all

http://javidan.github.io/jkeyboard/examples/index.htm
by running the following command from a script running as root in /usr/lib/cgi-bin:

Code: Select all

sudo -u pi chromium-browser --start-fullscreen http://javidan.github.io/jkeyboard/examples/index.htm
Everything seems to work just fine. When I clone the github, copy the above example file to /usr/lib/cgi-bin/lib/src, rename it to Winput.html, and run the following script, all that happens is the screen pops up with a text input form. No keyboard.

Code: Select all

#! /bin/bash
Dir=/usr/lib/cgi-bin/lib/src
cd $Dir
echo 'Content-type: text/html'
echo ""
cat $Dir/Winput.html
I don't spot any errors from the output of the script:

Code: Select all

Content-type: text/html

<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Keyboard Example</title>
    <link rel="stylesheet" href="/usr/lib/cgi-bin/lib/css/jkeyboard.css">
    <style>
        body{
            background: #144766
        }
        #search_field{
            display: block;
            margin: 0 auto;
            padding: 5px 10px;
            font-size: 28px; 
            width: 50%;
        }
            
    </style>
</head>
<body>
    
    <input type="text" id="search_field">
    

<div id="keyboard">
<ul class="jkeyboard">
        <li class="jline">
                <ul>
                        <li class="jkey letter">q</li>
                        <li class="jkey letter">w</li>
                        <li class="jkey letter">e</li>
                        <li class="jkey letter">r</li>
                        <li class="jkey letter">t</li>
                        <li class="jkey letter">y</li>
                        <li class="jkey letter">u</li>
                        <li class="jkey letter">i</li>
                        <li class="jkey letter">o</li>
                        <li class="jkey letter">p</li>
                </ul>
        </li>
        <li class="jline">
                <ul>
                        <li class="jkey letter">a</li>
                        <li class="jkey letter">s</li>
                        <li class="jkey letter">d</li>
                        <li class="jkey letter">f</li>
                        <li class="jkey letter">g</li>
                        <li class="jkey letter">h</li>
                        <li class="jkey letter">j</li>
                        <li class="jkey letter">k</li>
                        <li class="jkey letter">l</li>
                </ul>
        </li>
        <li class="jline">
                <ul>
                        <li class="jkey shift">&nbsp;</li>
                        <li class="jkey letter">z</li>
                        <li class="jkey letter">x</li>
                        <li class="jkey letter">c</li>
                        <li class="jkey letter">v</li>
                        <li class="jkey letter">b</li>
                        <li class="jkey letter">n</li>
                        <li class="jkey letter">m</li>
                        <li class="jkey backspace">&nbsp;</li>
                </ul>
        </li>
        <li class="jline">
                <ul>
                        <li class="jkey numeric_switch">123</li>
                        <li class="jkey layout_switch">&nbsp;</li>
                        <li class="jkey space">&nbsp;</li>
                        <li class="jkey return">Enter</li>
                </ul>
        </li>
</ul>
</div>
<script src="http://code.jquery.com/jquery-1.10.1.min.js"></script>
<script src="/usr/lib/cgi-bin/lib/src/jkeyboard.js"></script>
<script>
        $('#keyboard').jkeyboard({
        layout: "english",
        input: $('#search_field')
        });
</script>
</body>
</html>
There are no errors in apache2 or syslog, and only what look to be ordinary reports in auth.log, but there is an error reported by chromium when I run either the local script or the web URL:

Code: Select all

[9236:9236:1106/153237.208994:ERROR:sandbox_linux.cc(344)] InitializeSandbox() called with multiple threads in process gpu-process.
I can run the code externally, and when I run the inspector on FireFox, I get:

Code: Select all

Loading failed for the <script> with source “http://192.168.1.26/usr/lib/cgi-bin/lib/src/jkeyboard.js”. Winput.cgi:79
[Show/hide message details.] TypeError: $(...).jkeyboard is not a function[Learn More]
This is jkeyboard.js:

Code: Select all

Thermostat-Leslie:/usr/lib/cgi-bin/lib/src# cat jkeyboard.js 

// the semi-colon before function invocation is a safety net against concatenated
// scripts and/or other plugins which may not be closed properly.
; (function ($, window, document, undefined) {

    // undefined is used here as the undefined global variable in ECMAScript 3 is
    // mutable (ie. it can be changed by someone else). undefined isn't really being
    // passed in so we can ensure the value of it is truly undefined. In ES5, undefined
    // can no longer be modified.

    // window and document are passed through as local variable rather than global
    // as this (slightly) quickens the resolution process and can be more efficiently
    // minified (especially when both are regularly referenced in your plugin).

    // Create the defaults once
    var pluginName = "jkeyboard",
        defaults = {
            layout: "english",
            input: $('#input'),
            customLayouts: {
                selectable: []
            }
        };


    var function_keys = {
        backspace: {
            text: '&nbsp;',
        },
        return: {
            text: 'Enter'
        },
        shift: {
            text: '&nbsp;'
        },
        space: {
            text: '&nbsp;'
        },
        numeric_switch: {
            text: '123',
            command: function () {
                this.createKeyboard('numeric');
                this.events();
            }
        },
        layout_switch: {
            text: '&nbsp;',
            command: function () {
                var l = this.toggleLayout();
                this.createKeyboard(l);
                this.events();
            }
        },
        character_switch: {
            text: 'ABC',
            command: function () {
                this.createKeyboard(layout);
                this.events();
            }
        },
        symbol_switch: {
            text: '#+=',
            command: function () {
                this.createKeyboard('symbolic');
                this.events();
            }
        }
    };


    var layouts = {
        selectable: ['azeri', 'english', 'russian'],
        azeri: [
            ['q', 'ü', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p', 'ö', 'ğ'],
            ['a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', 'ı', 'ə'],
            ['shift', 'z', 'x', 'c', 'v', 'b', 'n', 'm', 'ç', 'ş', 'backspace'],
            ['numeric_switch', 'layout_switch', 'space', 'return']
        ],
        english: [
            ['q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p',],
            ['a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l',],
            ['shift', 'z', 'x', 'c', 'v', 'b', 'n', 'm', 'backspace'],
            ['numeric_switch', 'layout_switch', 'space', 'return']
        ],
        russian: [
            ['й', 'ц', 'у', 'к', 'е', 'н', 'г', 'ш', 'щ', 'з', 'х'],
            ['ф', 'ы', 'в', 'а', 'п', 'р', 'о', 'л', 'д', 'ж', 'э'],
            ['shift', 'я', 'ч', 'с', 'м', 'и', 'т', 'ь', 'б', 'ю', 'backspace'],
            ['numeric_switch', 'layout_switch', 'space', 'return']
        ],
        numeric: [
            ['1', '2', '3', '4', '5', '6', '7', '8', '9', '0'],
            ['-', '/', ':', ';', '(', ')', '$', '&', '@', '"'],
            ['symbol_switch', '.', ',', '?', '!', "'", 'backspace'],
            ['character_switch', 'layout_switch', 'space', 'return'],
        ],
        numbers_only: [
            ['1', '2', '3',],
            ['4', '5', '6',],
            ['7', '8', '9',],
            ['0', 'return', 'backspace'],
        ],
        symbolic: [
            ['[', ']', '{', '}', '#', '%', '^', '*', '+', '='],
            ['_', '\\', '|', '~', '<', '>'],
            ['numeric_switch', '.', ',', '?', '!', "'", 'backspace'],
            ['character_switch', 'layout_switch', 'space', 'return'],

        ]
    }

    var shift = false, capslock = false, layout = 'english', layout_id = 0;

    // The actual plugin constructor
    function Plugin(element, options) {
        this.element = element;
        // jQuery has an extend method which merges the contents of two or
        // more objects, storing the result in the first object. The first object
        // is generally empty as we don't want to alter the default options for
        // future instances of the plugin
        this.settings = $.extend({}, defaults, options);
        // Extend & Merge the cusom layouts
        layouts = $.extend(true, {}, this.settings.customLayouts, layouts);
        if (Array.isArray(this.settings.customLayouts.selectable)) {
            $.merge(layouts.selectable, this.settings.customLayouts.selectable);
        }
        this._defaults = defaults;
        this._name = pluginName;
        this.init();
    }

    Plugin.prototype = {
        init: function () {
            layout = this.settings.layout;
            this.createKeyboard(layout);
            this.events();
        },

        createKeyboard: function (layout) {
            shift = false;
            capslock = false;

            var keyboard_container = $('<ul/>').addClass('jkeyboard'),
                me = this;

            layouts[layout].forEach(function (line, index) {
                var line_container = $('<li/>').addClass('jline');
                line_container.append(me.createLine(line));
                keyboard_container.append(line_container);
            });

            $(this.element).html('').append(keyboard_container);
        },

        createLine: function (line) {
            var line_container = $('<ul/>');

            line.forEach(function (key, index) {
                var key_container = $('<li/>').addClass('jkey').data('command', key);

                if (function_keys[key]) {
                    key_container.addClass(key).html(function_keys[key].text);
                }
                else {
                    key_container.addClass('letter').html(key);
                }

                line_container.append(key_container);
            })

            return line_container;
        },

        events: function () {
            var letters = $(this.element).find('.letter'),
                shift_key = $(this.element).find('.shift'),
                space_key = $(this.element).find('.space'),
                backspace_key = $(this.element).find('.backspace'),
                return_key = $(this.element).find('.return'),

                me = this,
                fkeys = Object.keys(function_keys).map(function (k) {
                    return '.' + k;
                }).join(',');

            letters.on('click', function () {
                me.type((shift || capslock) ? $(this).text().toUpperCase() : $(this).text());
            });

            space_key.on('click', function () {
                me.type(' ');
            });

            return_key.on('click', function () {
                me.type("\n");
                me.settings.input.parents('form').submit();
            });

            backspace_key.on('click', function () {
                me.backspace();
            });

            shift_key.on('click', function () {
                if (capslock) {
                    me.toggleShiftOff();
                    capslock = false;
                } else {
                    me.toggleShiftOn();
                }
            }).on('dblclick', function () {
                capslock = true;
            });


            $(fkeys).on('click', function () {
                var command = function_keys[$(this).data('command')].command;
                if (!command) return;

                command.call(me);
            });
        },

        type: function (key) {
            var input = this.settings.input,
                val = input.val(),
                input_node = input.get(0),
                start = input_node.selectionStart,
                end = input_node.selectionEnd;

            var max_length = $(input).attr("maxlength");
            if (start == end && end == val.length) {
                if (!max_length || val.length < max_length) {
                    input.val(val + key);
                }
            } else {
                var new_string = this.insertToString(start, end, val, key);
                input.val(new_string);
                start++;
                end = start;
                input_node.setSelectionRange(start, end);
            }

            input.trigger('focus');

            if (shift && !capslock) {
                this.toggleShiftOff();
            }
        },

        backspace: function () {
            var input = this.settings.input,
                val = input.val();

            input.val(val.substr(0, val.length - 1));
        },

        toggleShiftOn: function () {
            var letters = $(this.element).find('.letter'),
                shift_key = $(this.element).find('.shift');

            letters.addClass('uppercase');
            shift_key.addClass('active')
            shift = true;
        },

        toggleShiftOff: function () {
            var letters = $(this.element).find('.letter'),
                shift_key = $(this.element).find('.shift');

            letters.removeClass('uppercase');
            shift_key.removeClass('active');
            shift = false;
        },

        toggleLayout: function () {
            layout_id = layout_id || 0;
            var plain_layouts = layouts.selectable;
            layout_id++;

            var current_id = layout_id % plain_layouts.length;
            return plain_layouts[current_id];
        },

        insertToString: function (start, end, string, insert_string) {
            return string.substring(0, start) + insert_string + string.substring(end, string.length);
        }
    };

    // A really lightweight plugin wrapper around the constructor,
    // preventing against multiple instantiations
    $.fn[pluginName] = function (options) {
        return this.each(function () {
            if (!$.data(this, "plugin_" + pluginName)) {
                $.data(this, "plugin_" + pluginName, new Plugin(this, options));
            }
        });
    };

})(jQuery, window, document);

bzt
Posts: 374
Joined: Sat Oct 14, 2017 9:57 pm

Re: javascript not working on RPi 3

Sat Nov 10, 2018 11:35 am

Hi,

since you got no responses at all, I'll try to answer.

First of all, your problem is not Raspberry related. Second, as you have admitted, you have serious shortage of required knowledge. I'll try to explain a few thing to shed some light on the topic.

Server client architecture
The web is using the so called server client architecture, in which client is a webbrowser, and server is webserver. They are usually not on the same machine (although you can put them on the same Raspberry as you did). They supposed to communicate over the network: the client (chromium/Firefox/opera etc.) sends a query with an URL to the server (apache/nginx/lighttpd etc.) using the HTTP protocol. The server accepts that query, examines the URL and decides what to do with it. If a file exists on the server's local filesystem, it sends that file as a response. If not, it can call a script to generate the response (CGI). If neither can be done, it sends a HTTP 404 File Not Found response. The response most often is a HTML, which is a descriptive language that tells the browser how to display things (what text to display, where to put images etc.). CSS is another descriptive language, called stylesheets, which is a collection of styles to be used when displaying a HTML (font face and font size of the text, image maximum size and alignment etc.). Note this is really just an introductory description in a nutshell.

Java has nothing to do with JavaScript.
Java is a compiled bytecode language, running in a virtual machine (jvm). You can run java bytecode on the server side and on the client side as well (the former called java application, the latter called java-applet and run by the jvm built into your browser, not by the java installed on the server. Lately that technology is abadoned in favour of HTML5 and JavaScript, but server side java is still used in many places, mostly by big companies and banks). Unlike java, JavaScript is an interpreted script language, and has no well-defined bytecode representation at all, and you don't compile it either.

JavaScript is not running as CGI
CGI means the script is called by the webserver, therefore interpreted on the server side. Because JavaScript is interpreted on client side in the browser, there's no such thing running JavaScript as a CGI (let's put node.js aside as you're clearly not using that framework). You are using shell script as CGI btw, interpreted by "/bin/bash".

You won't see JavaScript errors in apache logs
As mentioned before, JS is running in your browser, so there's no point in looking for logs on the server. As you have figured out, JS logs can be found in the browser, on the interface called Console. Both chromium and Firefox can run your JS code, and they both have that Console under their Inspector.

About the chromium message
That's perfectly normal when an instance is already running. Don't care about it.

About the JS Console message
As the Firefox message says, your JS does not define the jkeyboard function. And indeed, if you search for the string "function jkeyboard" in your js file, you'll find none.

About your jkeyboard.js file
It's a bit misleading, but what you have here is not JavaScript at all. It's a jQuery plugin. As such, it requires the jQuery framework in order to work. The jQuery framework is written in JavaScript, which can be interpreted by the browser. To make it a bit clearer, your js file is referencing the '$' object. There's no such thing in JavaScript, that's defined by jQuery. Without the jQuery framework, your browser does not know what to do with it.

Again, your problem is not Raspberry Pi related, so I'd suggest to visit jQuery related forums, there's a good chance you'll find your answer there.

Hope this helps a bit,
bzt

Heater
Posts: 12714
Joined: Tue Jul 17, 2012 3:02 pm

Re: javascript not working on RPi 3

Sun Nov 11, 2018 7:23 am

lrhorer,
When I clone the github, copy the above example file to /usr/lib/cgi-bin/lib/src, rename it to Winput...
I really don't think you should be putting example.html into any cgi bin or lib directory. example.html is just a plain old HTML file, it does not contain any PHP or whatever that is to be run by the webserver as CGI. example.html could as well be served from /var/www/ like any other static HTML page.
..., and run the following script, all that happens is the screen pops up with a text input form. No keyboard.
Well yes. Because the example.html requires to load two pieces of javascript as shown by the script tags it contains:

<script src="http://code.jquery.com/jquery-1.10.1.min.js"></script>
<script src="../lib/js/jkeyboard.js"></script>


The jquery-1.10.1.min.js is being loaded from code.jquery.com so be sure the browser you are viewing with can reach the internet.

No doubt it is not finding jkeyboard.js because you have not moved that file to any place the web server can serve it.

Be sure to put jkeyboard.js into a proper place on your server and change the script tag in example.html to point to it.

Which is what the Firefox error message is telling you:

Loading failed for the <script> with source “http://192.168.1.26/usr/lib/cgi-bin/lib ... eyboard.js”. Winput.cgi:79


Means your server does not have jkeyboard.js at the given URL /usr/lib/cgi-bin/lib/src/. Personally I don't think .js files should be in that cgi directory either. Put them somewhere under your /var/www and change that URL in example.html

[Show/hide message details.] TypeError: $(...).jkeyboard is not a function[Learn More]

Means it cannot find the function jkeyboard. Of cours enot because that function is in jkeyboard.js which failed to load.

lrhorer
Posts: 47
Joined: Sun Feb 22, 2015 6:35 pm

Re: javascript not working on RPi 3

Mon Nov 12, 2018 5:54 pm

First of all, your problem is not Raspberry related.
That is an assumption, and making unnecessary and especially undocumented assumptions is a bad idea when troubleshooting. I admit it doesn't seem most likely to be an issue related to the RPi, or more properly Raspbian, but I have documented significantly different behavior of Apache 2.4.25 under Raspbian Stretch than Apache 2.4.10 under Debian Jessie. The point is, virtually the exact same code running on my RPi behaves very differently than the same code - verified by inspector - running on his server.
Server client architecture
I did not say I was new at computing. I have been doing this for more than 40 years. I've written a few servers and more than a few clients. I am just not an expert at HTML or CGI. Not being an expert does not mean I am not familiar with the concepts.
Java has nothing to do with JavaScript.
So I have been informed. As I admitted, I have never worked with either. Not knowing the verbs, syntax, or punctuation rules of javascript, troubleshooting it by myself is a significant undertaking.
JavaScript is not running as CGI
Yeah, OK. Put it however you like. The point is, one difference, significant or not, between the example web server and the same code being served by my web server is the fact mine is being produced by a CGI script rather than being directly read by my web server. Although once again I find it unlikely the addition of

Code: Select all

Content-type: text/html
(blank line)
to the HTML page would make a difference to the jquery call, but it is possible. Regardless, it is a data point, and someone more expert than I may consider it significant. Thus, I needed to report it.
You won't see JavaScript errors in apache logs
Of course not. The same goes for syslog. Reporting the fact there are no errors more or less eliminates Apache and CGI script errors as the culprit. That is an important data point, and the first thing I would ask of anyone reporting trouble. Any such errors would need to be fixed first before moving on.
About the chromium message
That's perfectly normal when an instance is already running. Don't care about it.
Except that an instance is not running. This is what I get if an instance is running:

Code: Select all

Thermostat-Leslie:/usr/lib/cgi-bin# Created new window in existing browser session.
Created new window in existing browser session.
with no error at all. Once again, it seems very unlikely this is related to the problem at hand, since it is reported whether the code is served from his server or mine, but until we know what the problem actually is, we can't say with any authority, and it needs to be reported with the incident.
About the JS Console message
As the Firefox message says, your JS does not define the jkeyboard function. And indeed, if you search for the string "function jkeyboard" in your js file, you'll find none.
Granted, but then neither does the JS script on his server. More to the point, they are *EXACTLY* the same script. I did not do anything to the script other than clone the entire repository to my RPi. Furthermore, the entire script topology was transferred to the RPi by the cloning. If there were any problems with file permissions or locations, then it would be reported by Apache and / or by running the CGI script from the command line. So why do both Chrome and FireFox on two different systems complain about the exact same script, with the exception of the header required by the CGI interpreter, served from my RPi but not his server?
It's a bit misleading, but what you have here is not JavaScript at all. It's a jQuery plugin. As such, it requires the jQuery framework in order to work. The jQuery framework is written in JavaScript, which can be interpreted by the browser. To make it a bit clearer, your js file is referencing the '$' object. There's no such thing in JavaScript, that's defined by jQuery. Without the jQuery framework, your browser does not know what to do with it.
Isn't that provided by jquery-1.10.1.min.js? I have tried both a local copy and one served from code.jquery.com, as his script does. Either way, the jquery-1.10.1.min.js code loads without error.
Again, your problem is not Raspberry Pi related, so I'd suggest to visit jQuery related forums
OK, I found one. I will report there.

lrhorer
Posts: 47
Joined: Sun Feb 22, 2015 6:35 pm

Re: javascript not working on RPi 3

Mon Nov 12, 2018 7:18 pm

This does not appear to be a JQuery error nor a problem with the jkeyboard plugin. Note the issue is with the script not loading, not with the syntax of the script. Actually, I am not sure why Apache is not spawning an error, but from the HTTP stream:

Code: Select all

<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>404 Not Found</title>
</head><body>
<h1>Not Found</h1>
<p>The requested URL /keyboard/lib/css/jkeyboard.css was not found on this server.</p>
<hr>
<address>Apache/2.4.25 (Raspbian) Server at 192.168.1.26 Port 80</address>
</body></html>
and

Code: Select all

<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>404 Not Found</title>
</head><body>
<h1>Not Found</h1>
<p>The requested URL /keyboard/lib/src/jkeyboard.js was not found on this server.</p>
<hr>
<address>Apache/2.4.25 (Raspbian) Server at 192.168.1.26 Port 80</address>
</body></html>
Note I moved the repository from /usr/lib/cgi-bin/ to /keyboard/ to make sure it wasn't a permissions issue with /usr/lib/cgi-bin.

lrhorer
Posts: 47
Joined: Sun Feb 22, 2015 6:35 pm

Re: javascript not working on RPi 3

Mon Nov 12, 2018 7:49 pm

OK, I fixed it. Depending on exactly how I specified the URLs, Apache either thought the JS files were scripts executable on the server, rather than the browser, or else they were in a location Apache refused to read. I moved everything not CGI related to /var/www/html/lib, and now it works.

lrhorer
Posts: 47
Joined: Sun Feb 22, 2015 6:35 pm

Re: javascript not working on RPi 3

Mon Nov 12, 2018 7:52 pm

What I still don't quite understand is why Apache does not log 404 errors. Had it done so, I would have figured this out much earlier.

User avatar
DougieLawson
Posts: 35381
Joined: Sun Jun 16, 2013 11:19 pm
Location: Basingstoke, UK
Contact: Website Twitter

Re: javascript not working on RPi 3

Tue Nov 13, 2018 8:30 am

lrhorer wrote:
Mon Nov 12, 2018 7:52 pm
What I still don't quite understand is why Apache does not log 404 errors. Had it done so, I would have figured this out much earlier.
Apache does log 404 errors /var/log/apache2/access.log (here's a couple of redacted log entries).

Code: Select all

example.com:80 ???.???.???.254 - - [13/Nov/2018:08:25:49 +0000] "GET /404 HTTP/1.1" 404 402 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.77 Safari/537.36"
example.com:80 ???.???.???.254 - - [13/Nov/2018:08:25:51 +0000] "GET /favicon.ico HTTP/1.1" 404 409 "http://example.com/404" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.77 Safari/537.36"
Note: Having anything remotely humorous in your signature is completely banned on this forum.

Any DMs sent on Twitter will be answered next month.

This is a doctor free zone.

Heater
Posts: 12714
Joined: Tue Jul 17, 2012 3:02 pm

Re: javascript not working on RPi 3

Tue Nov 13, 2018 1:51 pm

lrhorer,
OK, I fixed it. Depending on exactly how I specified the URLs, Apache either thought the JS files were scripts executable on the server, rather than the browser, or else they were in a location Apache refused to read. I moved everything not CGI related to /var/www/html/lib, and now it works.
Which is what I explained above. Glad you got it working.
What I still don't quite understand is why Apache does not log 404 errors. Had it done so, I would have figured this out much earlier.
I'm very sure if you look in Apache's access.log you will see the request for your .js file logged along with the HTML error code returned to your browser.

You did not really need that because you already had the error that the browser gave you:

Loading failed for the <script> with source “http://192.168.1.26/usr/lib/cgi-bin/lib ... eyboard.js”. Winput.cgi:79

Apache does not log such things to an error log because it's not an error. Clients requesting URL's that don't exist is not a Apache error it's a normal occurrence.

Now, if a user points his browser at a non-existent URL the browser will no doubt display the 404 error. However in this case the page was loading fine but the .js it wanted to load subsequently was not found and no error is displayed. This is typical behavior.

Arguably this is poor page design. Either the page should continue to work, albeit with the missing functionality of the .js it could not load. Or it should not try to continue and indicate some failure.

lrhorer
Posts: 47
Joined: Sun Feb 22, 2015 6:35 pm

Re: javascript not working on RPi 3

Tue Nov 13, 2018 9:17 pm

Which is what I explained above. Glad you got it working.
Yes, it was. As it happens, I didn't read your explanation until I had already fixed it, but your input would have led me directly there. Thank you.
I'm very sure if you look in Apache's access.log
No doubt. I have since restarted Apache, so the logs of the event are gone. The access file is very verbose, yet a bit cryptic. That said, in the future I will know to look for 404 errors in the access file if something isn't loading.
You did not really need that because you already had the error that the browser gave you
Yes, and I did take note of the fact it was not loading, but I was expecting a file error in the error log. Obviously, I was mistaken.
Apache does not log such things to an error log because it's not an error. Clients requesting URL's that don't exist is not a Apache error it's a normal occurrence.
I would disagree, but then I am not the Apache developer. Certainly if a CGI script requests a non-existent resource, Apache logs an error. Not knowing any better, I would expect Apache to do the same if an HTML script requests a non-existent resource. Obviously, you are correct and I was mistaken. It just seems logical to me that Apache should log as an error any request for a non-existent resource. And yes, I know it gets logged in the access log, but every request gets logged there.
This is typical behavior.
Yes, but confusing behavior. I submit I was not the only one confused by it. I asked around to a number of my friends and colleagues who have done much more HTML code than I, and none of them caught it.
Arguably this is poor page design. Either the page should continue to work, albeit with the missing functionality of the .js
Well, technically it does. I could type data into the form from a real keyboard, etc, but since the entire functionality of the page centers around the pop-up keyboard, it's rather a moot point.
Or it should not try to continue and indicate some failure
I could not agree more there should be some more descriptive and clear failure notification, whether the page functions continue or not..

Again, thank you so very much for your assistance and instruction. It has been very valuable, and will without question serve me well in the future.

Heater
Posts: 12714
Joined: Tue Jul 17, 2012 3:02 pm

Re: javascript not working on RPi 3

Wed Nov 14, 2018 2:19 am

lrhorer,
I would disagree, but then I am not the Apache developer. Certainly if a CGI script requests a non-existent resource, Apache logs an error. Not knowing any better, I would expect Apache to do the same if an HTML script requests a non-existent resource.
There is a good reason for this behavior and with a bit of though it makes sense.

When a page in your browser requests a missing .js file that is the same as any browser user requesting a non-existent URL. The server does not know if that request is from a web page it just served up or from a user manually entering the URL.

If all requests for non-existent resources were logged as errors then the Apache error log would be flooded with millions of such requests. Drowning out any real errors in Apache or it's configuration.

A request for a non-existent resource is no more an error in the server than somebody going into a shop and asking for something the shop does not sell is an error in the shop.

lrhorer
Posts: 47
Joined: Sun Feb 22, 2015 6:35 pm

Re: javascript not working on RPi 3

Wed Nov 14, 2018 8:11 pm

There is a good reason for this behavior and with a bit of though it makes sense.
I understand the logic, I just don't quite agree with it. It creates a situation that in a case such as this is difficult to troubleshoot. Of course, now I know about it, I can avoid the pitfall in the future.
When a page in your browser requests a missing .js file that is the same as any browser user requesting a non-existent URL. The server does not know if that request is from a web page it just served up or from a user manually entering the URL.
Yes, of course, but in the latter case, a great, big, 404 Error gets blasted across the screen telling the person, developer or otherwise, the resource was not found. Arguably in the case I was encountering, it is a failure of the browser to inform the user of error in an obvious fashion, but since every browser - or at least all the ones I tried - behaves this way, it is hard to argue the browser is the application responsible for making the failure clear. Apache doesn't operate in a vacuum. It is a team effort between the server and its clients. Ideally, SOMETHING in the process should make any and all errors clear and evident. In a perfect world, both systems would make the error clear and evident. Now, on the other side of the coin, Apache *DID* report the error to the browser. It sent a 404 error to the browsers. All of them just gulped down the error without comment. That is not ideal behavior, either. To my mind, pointing fingers doesn't help, though. Please understand, I am definitely not blaming your understanding of the situation, and certainly I am not criticizing you. I'm not even criticizing Apache, exactly, but it is a failure mode engendered by the client-server architecture, so if you ask me, a more robust solution should have been implemented by agreement on both sides of the fence.
If all requests for non-existent resources were logged as errors then the Apache error log would be flooded with millions of such requests. Drowning out any real errors in Apache or it's configuration.
As opposed to drowning in the access log, which is the only place it was evident on the server side? No matter what, the access log is going to be more voluminous than the error log. I suppose an access error log would make the best of both worlds, keeping the main error log thin while making resource errors more obvious. It's just to me a distinction between a resource error in a CGI script, a web page, or a human being making a typo is superficial. It is a resource error, either way. I suppose a debug / verbose error mode usable by the developer might also be a useful tool. Turn on debug and let the error log get fat when there is an issue. Turn it off when the issue is resolved.
A request for a non-existent resource is no more an error in the server than somebody going into a shop and asking for something the shop does not sell is an error in the shop.
But it *IS* an error in the shop. Stretching the analogy too far obviously breaks it, but the shop keeper is responsible for everything in his shop, including a lack of inventory. It's a little more like going into a shop with a servant who requests something of the shop-keeper. The shop keeper then informs the servant the item is not available. Then, instead of passing that information on to his master, the servant remains silent. The keeper insists it is not his job to inform his customer, and the servant insists it is not his job to inform his master. So, which one is at fault? The "it's not my job" mentality is what is at fault. I would argue something similar is going on here. There aren't two different shops, here, a client shop and a server shop. There is only a client-server shop. Feel free to disagree. It is a corner issue, but frustrating nonetheless.

bzt
Posts: 374
Joined: Sat Oct 14, 2017 9:57 pm

Re: javascript not working on RPi 3

Fri Nov 16, 2018 11:45 am

lrhorer wrote:
Mon Nov 12, 2018 5:54 pm
First of all, your problem is not Raspberry related.
That is an assumption, and making unnecessary and especially undocumented assumptions is a bad idea when troubleshooting.
Nope, that wasn't an assumption, that's a fact. I made a well-educated guess based on many years of experience. Now that you have fixed it you can see that too.
Irhorer wrote:I understand the logic, I just don't quite agree with it.
Then you can configure your apache to log those as well. It's up to you, you can use different configurations than the default one. But keep in mind there's a good reason why the default is as it is. (Look for the custom log option and setting log severity level.) That's one reason why serious webdevelopers have separated testing and production environments with different apache configs.
Irhorer wrote:But it *IS* an error in the shop.
I'd like to disagree. If you go to a hardware store, demaning fish & chips, I don't think that's an error on the shop's side nor do I think the shop should do anything about it (no need to open an account for you or to accept a complaint). All the shop can do is telling you, "we don't sell those" (equivalent of 404 Not Found).

Cheers,
bzt

lrhorer
Posts: 47
Joined: Sun Feb 22, 2015 6:35 pm

Re: javascript not working on RPi 3

Fri Nov 16, 2018 6:38 pm

Nope, that wasn't an assumption, that's a fact. I made a well-educated guess based on many years of experience.
A guess, stated as if it were fact, is the same thing as an assumption, with the same potential results. It is an implication, and any inference drawn upon it and acted upon as if it were verified is liable to be in error. I have also been at this for many years. I have been working as a scientist and then as an engineer for over 40 years.

The first postulate of science is, "There exists a real, physical world". The notion is not often debated, but it is, nonetheless, an assumption, literally thousands of years of observation notwithstanding. It may not be ultimately correct, and the implications of it being in error are far greater reaching than the nature of a Raspberry Pi. That said, the hypothesis of any seasoned professional such as yourself is extremely likely to be correct, as has been demonstrated in this case.
Then you can configure your apache to log those as well.
Well, it's a chicken / egg situation, or Catch-22, if you prefer. I would have had to be aware of the potential issue in order to re-configure the logs, but knowing of the issue, I don't need the logs re-configured. On the other hand, I am not the only one who had some trouble figuring this out.
That's one reason why serious webdevelopers have separated testing and production environments with different apache configs.
Indubitably. I am not a web developer, serious or otherwise. I just needed this one, simple page to work for a hardware project I am developing on a shoestring. If I had the funds, I would have hired a seasoned developer such as yourself to do the work. On that note, thank you so much, once again.
But keep in mind there's a good reason why the default is as it is.
I will certainly allow that. Is it the BEST reason, though? To put it differently, is there a better way to serve both viewpoints, not just one. I think there is, but yet again, I must admit I am not the developer of Apache nor the maintainer of the package.
I'd like to disagree.
Please feel free to do so. It won't upset me. Differing viewpoints make this world a much richer place, and a polite discussion at worst is enjoyable. At best, it may spark new ideas or new ways of approaching the issues at hand.
If you go to a hardware store, demaning fish & chips, I don't think that's an error on the shop's side
I didn't say it was an error on the shop's side, just within the confines of the shop. If a customer mistook one of the displays for a functioning urinal, I am quite sure the shop owner would have something to say about it, even though it is not an error on the part of the shop. If that customer asks for fish & chips, the owner (or clerk) should inform the customer of his error.
All the shop can do is telling you, "we don't sell those" (equivalent of 404 Not Found).
That is doing something. Back in the context of the client-server relationship, the user (or developer) and the client-server engine are all part of a single unit. The best code accommodates the functioning of the entire system, not just the client, not just the server, and not just the client-server. The user is, after all, the entire reason the code exists. As you mentioned earlier, of course, the operational and reporting environment may be much different for the end user than for the developer. I happened to fall somewhere in the middle. If you ask me, it is a great advantage of these sorts of forums that they can meet the needs of those such as I. It certainly saved my bacon.

Oh, by the way, if you or anyone else looking on is interested, I will have the web page exposed to the internet for a short while. Anyone may take a look here:

http://fletchergeek.homelinux.net:8080/ ... board.html

It will likely look a little odd on most people's monitors, but it renders properly on the 800 x 640 touchscreen of the Raspberry Pi.

Heater
Posts: 12714
Joined: Tue Jul 17, 2012 3:02 pm

Re: javascript not working on RPi 3

Fri Nov 16, 2018 7:45 pm

Looks good, till I hit "enter" then it all goes white.

lrhorer
Posts: 47
Joined: Sun Feb 22, 2015 6:35 pm

Re: javascript not working on RPi 3

Sat Nov 17, 2018 2:59 am

Yep. It's performing a GET to a CGI script which writes to wpa_supplicant.conf and completes by killing itself and its ancestors. Of course, on your machine, this does nothing, On the Raspberry Pi, it shuts down Chrome, because it is no longer useful, and brings the desktop back up.

bzt
Posts: 374
Joined: Sat Oct 14, 2017 9:57 pm

Re: javascript not working on RPi 3

Sat Nov 17, 2018 1:16 pm

Hi,

Looks good! Despite you're not a webdeveloper, you did a great job!

I'd like to add one thing on security side: you should use a POST method (add "method='POST'" to the form tag). Right now your apache logs as well as the browser history stores those passwords in clear text. POST won't send the form fields in the url, rather in the http body, so apache logs and browser history won't contain sensitive information. It won't secure your connection though, if an attacker is sniffing your network packets, they will get the password regardless. You'd need SSL to avoid that, but that's another story.

Well done,
bzt

P.S.: not debating you, but I personally never heard
The first postulate of science is, "There exists a real, physical world".
we were taught that science is build on empirical facts and well-proven, testable deduction. Interestingly though, wikipedia on scientific method does not mention Euclid at all, allthough he invented the term axioms (equivalent of empirical fact in theoretical math), as well as the scientific reasoning and he was the first to write the famous "quod errat demonstrandum" (see wikiquotes), unavoidable in any theoretical scientific discusson. As a matter of fact, we were told at high school that scientific method will work even if we're happen to live in a hologram, an existing physical world is not necessairy at all.

Heater
Posts: 12714
Joined: Tue Jul 17, 2012 3:02 pm

Re: javascript not working on RPi 3

Sat Nov 17, 2018 10:57 pm

bzt,

Yes but:

First we have to define what a "fact" is. There are statements, there are statements we call "true", there are statements we call "false". The latter being known as facts. But what do we mean by "true"? And statements about what exactly?

Then, what is a "proof". What is it that constitutes a satisfactory proof of the truth of some statement?

Ah yes, deduction. Hmm...what does that mean? How does one deduce correctly?

This all seems kind of obvious after a typical high school education but it has taken smart minds thousands of years to get us to where we are today. Going back to the Greeks and before.

The way I see it, mathematical axioms and proofs are somewhat different to the "proofs" in science. Mathematicians can adopt whatever axioms they like and from there deduce all kinds of proofs, these need not have anything to do with the physical world as we have observed and measured. In fact scientists will say there are no proofs in science, only the best model we have at the time. The classic example is that of Newtonian gravity, one can deduce and "prove" all kinds of things from that, problem is that mathematical deduction needs to be verified against experiment, as you know that fell apart at the extremes and we had to move to relativity theory.

Anyway, the postulates of science are spelled out here: https://www.jstor.org/stable/185197?seq ... b_contents

Turns out we may we be living in a hologram, according to some theoretical physics models:
https://www.youtube.com/watch?v=2DIl3Hfh9tY
https://www.youtube.com/watch?v=z1-QDXReDTU
https://www.youtube.com/watch?v=XDAJinQL2c0

lrhorer
Posts: 47
Joined: Sun Feb 22, 2015 6:35 pm

Re: javascript not working on RPi 3

Sun Nov 18, 2018 12:04 am

Um, no. Of course, some of this boils down to semantics, but some is fundamental. First of all, I believe it was Kurt Gödel who showed that every formal system of dedction (mathematical, scientific, logical, whatever) must contain at least one assumption, also known as an axiom, a principle, or a postulate depending upon the discipline, and at least one undefined term. Most contain quite a few. Euclidean geometry, for example, contains 3 undefined terms and 5 postulates. It actually can be boiled down to two undefined terms, but then things get really messy. It is a very compact and concise discipline. Non-Euclidean geometry is even more compact, with only 4 of the 5 Euclidean postulates, but then it also consequently allows a great many seemingly nonsensical forms and relationships. As it turns out, however, Non-Euclidean geometry better describes the universe on a large scale than Euclidean geometry. It sometimes fails to make sense to us because we only live on a small scale, and have precious little experience with any large scale.

All of science requires the first postulate, and almost every theory we have assumes it, pretty much without even consideration or mention. It is there, nonetheless. There are at least a couple of hypotheses which do not depend upon and which ultimately refute the first postulate. A discussion of Quantum reality or mirroring of an N-dimensional surface in N-K dimensions in General Relativity is way, way beyond the scope of this forum, however.

Science has nothing to do with truth - look to philosophies such as Boolean logic, metaphysics, or epistemology for discussions involving truth.

Science does involve a notion of falsehood, however. Any theoretical prediction which fails to produce reconcilable values with subsequent empirical investigation is considered false, and the process of engaging is such research is called, "falsification".

A fact is not an article of some particular degree of certainty, and to be sure no fact is perfectly certain, ever. Most are not even all that close. A fact is merely a reproducible physical observation, often some sort of measurement. I can factually state the pill bottle sitting on my desk right now is 38mm in diameter. As facts go, it is not a terrible one, although the pill bottle can be more accurately measured as 37.76mm in diameter. Over time, our measuring instruments have generally improved more and more so that the facts relevant to them have gained in both precision and accuracy, changing usually by small increments.

A hypothesis is often called an. "educated guess", which is a pretty good description. It may or may not be based upon existing empirical data and / or well established principles. It is an idea which attempts to explain some phenomenon. Properly speaking, a hypothesis remains a hypothesis until someone deduces a likely result suggested by the hypothesis and then goes and tests it. If the experiment supports the hypothesis then (after peer review and repeated tests that continue to support the hypothesis), we call it a theory. A fact is not a theory that has become more certain. It is a completely different thing. Just as many facts get more refined over time, the theories relevant to them also may get refined. The nonetheless remain theories. There have been quite literally many tens of billions, perhaps even trillions of data points taken, very single one of which perfectly support the Special Theory and General Theory of Relativity, and effectively zero which have ever contradicted in an unexplicable way either, but they remain, nonetheless, theories.

Despite the name, a Law is not a more certainly verified theory. It is a single principle generalized from a number of varied specific observations. Generally, something is a Law if (within the area of its operational context) no significant violation has ever been observed. Many Laws are only approximations. The gas Laws, for example, are mostly approximations relative to some ideal gas.

And yes, some philosophies are empirical based, science being one example. Others are not empirically based. We generally demand that any acceptable discipline must be internally consistent, or else most scholars would reject it, or at least demand it be corrected. Science and other empirical philosophies demand the article in question be not only internally consistent, but also externally consistent.
Last edited by lrhorer on Sun Nov 18, 2018 1:25 am, edited 1 time in total.

lrhorer
Posts: 47
Joined: Sun Feb 22, 2015 6:35 pm

Re: javascript not working on RPi 3

Sun Nov 18, 2018 12:23 am

Anyway, the postulates of science are spelled out here
Correct, sort of, but if you will look closely, you will see every one of his categories have points that are derivative of the First Postulate. The 1st, 2md, 5th, and 10th postulates are actually derived from the First Postulate of Science. In the first place, if we do not assume there is a real, measurable, physical universe, then it is extremely difficult to assign meaning to any measurement or to claim any valid deductions therefrom. Not if one wishes to be concise and thorough. One could be horribly sloppy, I suppose, but that's not very good science.
Ah yes, deduction. Hmm...what does that mean? How does one deduce correctly?
There are very rigid and definitive tests for internal consistency. There are many people who provide ideas that are not internally consistent. I try to ignore them. Others provide internally consistent explanations that do not jibe with established facts. I usually point out such inconsistencies. Then there are those, like you, who provide suggestions that are both internally and externally consistent. I try hard to listen to them.
The way I see it, mathematical axioms and proofs are somewhat different to the "proofs" in science.
There is no proof in science, only evidence and speculation - and of course falsification, and scientific codification is known as "inference".
Turns out we may we be living in a hologram, according to some theoretical physics models
Yes, but as I said, such discussions are far beyond the scope of this forum. They are also highly speculative, beyond the limit of any hypothetical framework. In order to be considered a proper hypothesis, it must be falsifiable. At least as of now, there is no way to test these. It is fairly likely there never will be.

lrhorer
Posts: 47
Joined: Sun Feb 22, 2015 6:35 pm

Re: javascript not working on RPi 3

Sun Nov 18, 2018 1:45 am

I'd like to add one thing on security side: you should use a POST method (add "method='POST'" to the form tag).
I am aware of the implications for security, but since this page will never be available to the internet, or indeed across any network, the point is moot. Once the software development is done, this will only ever be served up to the console, and then only when the device is first being configured. There has to be a way to configure the SSID and Passphrase for wireless communications, but only if there is no hard-wired Ethernet. Once wireless networking is running, it will never run again. There is a completely different means of changing the SSID and passphrase if networking is already established using secure communications.

User avatar
DougieLawson
Posts: 35381
Joined: Sun Jun 16, 2013 11:19 pm
Location: Basingstoke, UK
Contact: Website Twitter

Re: javascript not working on RPi 3

Sun Nov 18, 2018 10:46 am

That's no excuse for sloppy security. It may not be connected today, it may be in the future.

What's so hard about doing it the right way now. You'll learn something in the process.
Note: Having anything remotely humorous in your signature is completely banned on this forum.

Any DMs sent on Twitter will be answered next month.

This is a doctor free zone.

Heater
Posts: 12714
Joined: Tue Jul 17, 2012 3:02 pm

Re: javascript not working on RPi 3

Sun Nov 18, 2018 11:00 am

If the page is never going to be served across any network I would be inclined to not use a webserver. Or at least not the likes of Apache etc.

Rather, use that web page with Electron and have the "backend" done in node.js within the same Electron application.

Electron is basically the Chrome browser rendering engine and V8 Javascript engine wrapped up as an application with node.js to take care of the non-web page parts that interact with your OS. It's what Etcher is build from.

bzt
Posts: 374
Joined: Sat Oct 14, 2017 9:57 pm

Re: javascript not working on RPi 3

Sun Nov 18, 2018 12:10 pm

Hi,

Uh, oh, it seems I've sidetracked the topic, sorry. I'll answer some of your questions to clearify things for you, but I don't want start a deep theoretical discusson about our universe if you don't mind.
Heater wrote:
Sat Nov 17, 2018 10:57 pm
First we have to define what a "fact" is. There are statements, there are statements we call "true", there are statements we call "false". The latter being known as facts. But what do we mean by "true"? And statements about what exactly?
You have messed up things a bit :-) First of all, this definition is not for facts. It's for logical statements in Boolean algebra. Any linguistic statement that can be clearly evaluated to a true or false is a logical statement. This is purely theoretical projection of things, has nothing to do with the observable world around us. Therefore the answer to "about what exactly" could be anything.
Second, if you make statements about observations on the real world which anybody can observe and ALWAYS evaluates to the same "true", regardless who, when and where is evaluating that statement, now that's a fact. For example: "The Sun is rising on the East". This is a statement about our world. It doesn't matter if you are old or young, boy or girl, live in the UK or in China, you can check the validity of that statement by observing, and all observations yields the same result, therefore that's a fact.
Then, what is a "proof". What is it that constitutes a satisfactory proof of the truth of some statement?
As you have written, "deduction needs to be verified against experiment". That stands for any kind of science, not just math. A theory must predict something that can be empirically checked with an experiment. It that regard experiments are nothing more than logic statements: can you conduct them with the same result or not? And that's how it works: if a scientist come up with a new theory, at least two, separated, independent labratory required to conduct the verification experiment with the same results to turn the theory into a fact. That's the scientific method.
(I'd like to point out that the "experiment" can be theoretical (just like with math and philosophy where you use math rules and logic) or empirical (like with chemistry, biology, physics etc. where you can use measurements). That doesn't matter. The point is, anybody can repeat the verification, and they are expected to get the same result for the hipotetichal theory to became a new fact.)
Ah yes, deduction. Hmm...what does that mean? How does one deduce correctly?
Err, hmm, we learned that at school... It's part of the Boolean algebra, and the rules have funny Latin names like modus ponendo ponens, modus tollendo ponens, modus ponendo tollens etc. Look them up.
This all seems kind of obvious after a typical high school education
I don't think so. To my experience it's quite the opposite. I used to be a university teacher, and I've found that many basic (even trivial) things about our world had to be explained to the first year students. For example they usually think there're math, biology, physics, etc. forgetting that having science branches is just an illusion. Those are nothing more than different projections of the same ONE WORLD we're live in. The evolution doesn't care if the tunnel effect is defined in physics, it will use that in biology as well if that makes the photosynthesis more effective. And indeed it does.
Anyway, the postulates of science are spelled out here: https://www.jstor.org/stable/185197?seq ... b_contents
Don't believe anything you find on the internet (specially not in this fake-news ruled era). All that I've said here, I learned from my teachers not from some obscure website. I was very luckily as I had great ones who taught me how to think. As that being said, don't believe blindly what I've said here either. Give it a though, conduct your own experiments to filter out what's the truth. ;-)

Cheers,
bzt

lrhorer
Posts: 47
Joined: Sun Feb 22, 2015 6:35 pm

Re: javascript not working on RPi 3

Sun Nov 18, 2018 7:24 pm

That's no excuse for sloppy security. It may not be connected today, it may be in the future.
No, this is an embedded application. If the end user hacks the platform and opens up the network, that's his problem. Otherwise it sits on the wall and responds to button presses on the front panel and broadcasts from other identical units on the network.
What's so hard about doing it the right way now. You'll learn something in the process.
Nothing really. I've already considered it, and I may reconsider before the project is done. Right now, at least, it is easier to troubleshoot if i can see the responses on the URL bar.

Return to “Other programming languages”