1

I'm having a problem with a page on my site chillingsafe.com/upload.php and I was hoping some of you would be able to help me.

Many 3G network providers compress web pages and images to lower the amount of data used, they do this by injecting this line of code script src="http://1.2.3.8/bmi-int-js/bmi.js" language="javascript" just after the opening html tag.

The problem with this is that not only does it downscale images, but it compresses your code and usually forces it onto a single line. After this is done my uploading system on my website will not work correctly. It actually causes this error which I found in Chromes console, Uncaught TypeError: Cannot read property 'innerHTML' of null. I understand what this means but I do not know how to fix it, especially when there is no problems at all on a standard broadband connection.

I would be grateful if someone could assist me on this.

Thanks, Joe

joedm
  • 27
  • 7
  • Please include the mentioned code, instead of a "script"-tag... – Mads K Mar 16 '14 at 13:43
  • It's quite a long script. – joedm Mar 16 '14 at 13:53
  • It must be doing more the just compressing(eg. removing whitespace), because otherwise it would not be an issue. By the way, which browsers are you using for testing? Older version of IE, fails when using the innerHTML. – Mads K Mar 16 '14 at 13:54
  • Both the latest versions of Chrome and Firefox. – joedm Mar 16 '14 at 13:59
  • Here is a screenshot of what the inject script does to the code http://help.chillingsafe.com/download/file.php?id=1 – joedm Mar 16 '14 at 14:06
  • Have you linted your code? It is quite possible you are missing a semicolon (or similar) somewhere. If it is huge, do you have a link to the script affected? – user13500 Mar 16 '14 at 14:49
  • Hello, I do have a link here http://chillingsafe.com/upload.php, the code is included on the page just after the header, it begins with var FileUrls = []; and I have looked many times for any mistakes but could not find any, I have rewrote the entire code once. I am really confused on this as it only seems to be happening on Google Chrome, it even works perfectly on my phone and on IE. Thank you. – joedm Mar 16 '14 at 15:05

1 Answers1

3

Had a quick look at your code. (The one inline/embedded in the main page.)

There are some issues here.

1.) You almost never use var. As a result all your variables are hoisted up to global space.

function foo() {
   answer = 42;
}
foo();

Now window.foo === 43, or simply foo if you like.

In one of your scopes you also have use strict. As a result the undefined variables will not be hoisted up, but you will typically get a:

Uncaught ReferenceError: somevariablename is not defined

2.) You never use hasOwnProperty() on your for in loops. Always use:

for (x in y) {
    if (y.hasOwnProperty(x)) {
        ....
    }
}

If it is an array never use for in but:

var i;
for (i = 0 ; y.length ;  ++i) {

}

In your code you do a lot of for in on arrays. Don't!

3.) On line 352 you are missing a semicolon:

html += '" onClick="">' // ««« Missing semicolon!
if (isSuccess == false) {
html += data.error_result_html;

4.) Inline comments.

If script get compressed by some poor implemented compressor inline codes are an issue:

var x = 123;
// some comment
alert(x);

could result in

var x = 123; // some comment alert(x);

5.) Cannot read property 'innerHTML' of null

Could mean some of your code is executed out of order. E.g. it is executed before DOM is ready. From what I can see only the last interval thing is outside the ready wrap of jQuery. Try to add it inside the wrapper as well.

$(document).ready(function () {

    ...

    function CheckTables() {
        $("table ").each(function (index) {
            $(this).find('tbody:empty').parent().hide();
            $(this).find('tbody:not(:empty)').parent().show();
        });
    }
    setInterval(CheckTables, 100);
});

You could also try to replace ready() with:

$(window).load(function() {

});

in both instances.


There might be more. Try fixing number 3 first.


A quick format and some comment and var insertions etc. from extracted code:


/* jshint sub:true, eqeqeq:false */
/* global $, ZeroClipboard, alert, bytesToSize, humanReadableTime */
/* exported updateTotalFilesText, setRowClasses, sendAdditionalOptions */
/* ============================================================================ */
var fileUrls = [];
var fileDeleteHashes = [];
var fileShortUrls = [];

var fileToEmail = '';
var filePassword = '';

var startTime = null;
var uploadComplete = false;
function getUrlsAsText() {
    var urlStr = '';
    for (var i = 0; i < fileUrls.length; i++) {
        urlStr += fileUrls[i] + "\n";
    }
    return urlStr;
}
function setupCopyAllLink() {
    $('#copyAllLink').attr('data-clipboard-text', getUrlsAsText());
    var clip = new ZeroClipboard(document.getElementById("copyAllLink"), {
        moviePath: "http://cdn.chillingsafe.com/scripts/zeroClipboard/ZeroClipboard.swf",
        text: getUrlsAsText()
    });
    clip.on('complete', function (client, args) {
        alert("" + args.text);
    });
}
function updateProgessText(progress, uploadedBytes, totalBytes) {
    var nowTime = (new Date()).getTime();
    var loadTime = (nowTime - startTime);
    if (loadTime === 0) {
        loadTime = 1;
    }
    var loadTimeInSec = loadTime / 1000;
    var bytesPerSec = uploadedBytes / loadTimeInSec;
    var textContent = '';
    textContent += '' + progress + '% complete';
    textContent += ' ';
    textContent += '(' + bytesToSize(uploadedBytes, 2) + ' of ' + bytesToSize(totalBytes, 2) + ')';
    $("#fileupload-progresstextLeft").html(textContent);
    var rightTextContent = '';
    rightTextContent += '' + humanReadableTime((totalBytes / bytesPerSec) - (uploadedBytes / bytesPerSec)) + ' remaining';
    rightTextContent += ' at ' + bytesToSize(bytesPerSec, 2) + 'P/s';
    $("#fileupload-progresstextRight").html(rightTextContent);
}
function updateTitleWithProgress(progress) {
    if (typeof (progress) == "undefined") {
        progress = 0;
    }
    if (progress === 0) {
        $(document).attr("title", "Upload - ChillingSafe");
    } else {
        $(document).attr("title", progress + "% complete - ChillingSafe");
    }
}
function getTotalRows() {
    var totalRows = $('#files .template-upload').length;
    if (typeof (totalRows) == "undefined") {
        return 0;
    }
    return totalRows;
}
function updateTotalFilesText(/*total*/) {
    //$('#uploadButton').html('upload '+total+' files');
}
function setRowClasses() {
    //$('#files tr').removeClass('even');
    //$('#files tr').removeClass('odd');
    //$('#files tr:even').addClass('odd');
    //$('#files tr:odd').addClass('even');
}
/* Never used
var lastEle = null;
function showAdditionalInformation(ele) {
    $('.sliderContent table').unbind();
    $('.sliderContent table').click(function (e) {
        e.stopPropagation();
    });
    if (lastEle == ele) {
        $('.sliderContent').slideUp('fast');
        $('.sliderContent').parent().parent().removeClass('rowSelected');
        lastEle = null;
        return false;
    }
    lastEle = ele;
    $('.sliderContent').slideUp('fast');
    $('.sliderContent').parent().parent().removeClass('rowSelected');
    $(ele).addClass('rowSelected');
    $(ele).find('.sliderContent').css('left', 21);
    $(ele).find('.sliderContent').css('top', $(ele).offset().top - 38  );
    $(ele).find('.sliderContent').slideDown(400, function () {});
    return false;
}

function saveFileToFolder(ele) {
    var shortUrl = $(ele).closest('.sliderContent').children('.shortUrlHidden').val();
    var folderId = $(ele).val();
    var request = $.ajax({
        url: "http://chillingsafe.com/folder_update.ajax.php",
        type: "POST",
        data: {
            shortUrl: shortUrl,
            folderId: folderId
        },
        dataType: "html"
    });
}
*/
function showAdditionalOptions() {
    if ($('#additionalOptionsWrapper').is(":visible")) {
        $('#additionalOptionsWrapper').slideUp();
    } else {
        $('#additionalOptionsWrapper').slideDown();
    }
}
/* Never used.
function saveAdditionalOptions() {
    fileToEmail = $('#send_via_email').val();
    filePassword = $('#set_password').val();
    processAddtionalOptions();
    showAdditionalOptions();
}
function processAddtionalOptions() {
    if (uploadComplete === false) {
        return false;
    }
    return sendAdditionalOptions();
}
*/
function sendAdditionalOptions() {
    if (fileDeleteHashes.length === 0) {
        return false;
    }
    if ((fileToEmail.length === 0) && (filePassword.length === 0)) {
        return false;
    }
    $.ajax({
        type: "POST",
        url: "http://chillingsafe.com/file_options.ajax.php",
        data: {
            fileToEmail: fileToEmail,
            filePassword: filePassword,
            fileDeleteHashes: fileDeleteHashes,
            fileShortUrls: fileShortUrls
        }
    }).done(function (/* msg */) {
        fileToEmail = '';
        filePassword = '';
    });
}


$(document).ready(function () {
    'use strict';
    /* global updateTotalFilesText, setRowClasses */
    var totalRows;

    $('#fileUpload #fileupload').fileupload({
        sequentialUploads: true,
        url: 'http://chillingsafe.com/upload_handler.php?r=chillingsafe.com&p=http',
        maxFileSize: 268435456 ,
        formData: {
            _sessionid: 'bfeadc6536fe586b347e4c18ced14482'
        },
        xhrFields: {
            withCredentials: true
        },
        maxNumberOfFiles: 100})
        .on('fileuploadadd', function (/* e, data */) {
            $('#fileUpload #fileupload #fileListingWrapper').removeClass('hidden');
            $('#fileUpload #fileupload #initialUploadSection').addClass('hidden');
            $('#fileUpload #fileUploadBadge').addClass('hidden');
            getTotalRows();
            totalRows = getTotalRows() + 1;
            updateTotalFilesText(totalRows);
        })
        .on('fileuploadstart', function (/* e, data */) {
            $('#fileUpload #addFileRow').addClass('hidden');
            $('#fileUpload #processQueueSection').addClass('hidden');
            $('#fileUpload #processingQueueSection').removeClass('hidden');
            $('#fileUpload .cancel').html('<img src="http://cdn.chillingsafe.com/images/pixel.png" style="margin:10px" id="upload-uploading"  />');
            startTime = (new Date()).getTime();
        })
        .on('fileuploadstop', function (e, data) {
            updateTitleWithProgress(100);
            updateProgessText(100, data.total, data.total);
            $('#fileUpload #processQueueSection').addClass('hidden');
            $('#fileUpload #processingQueueSection').addClass('hidden');
            $('#fileUpload #completedSection').removeClass('hidden');
            $('#fileUpload .processingIcon').parent().html('<img src="http://cdn.chillingsafe.com/images/red_error_small.png" width="16" height="16"/>');
            uploadComplete = true;
            sendAdditionalOptions();
            setupCopyAllLink();
        })
        .on('fileuploadprogressall', function (e, data) {
            var progress = parseInt(data.loaded / data.total * 100, 10);
            $('#progress .bar').css('width', progress + '%');
            updateTitleWithProgress(progress);
            updateProgessText(progress, data.loaded, data.total);
        })
        .on('fileuploaddone', function (e, data) {
            fileUrls.push(data['result'][0]['url']);
            fileDeleteHashes.push(data['result'][0]['delete_hash']);
            fileShortUrls.push(data['result'][0]['short_url']);
            var isSuccess = true;
            if (data['result'][0]['error'] !== null) {
                isSuccess = false;
            }
            var html = '';
            html += '<tr class="template-download';
            if (isSuccess === false) {
                html += ' errorText';
            }
            html += '" ';
            if (isSuccess === true) {
                html += 'onClick=""';
            }
            html += '>';
            if (isSuccess === true) {
                html += data['result'][0]['success_result_html'];
            } else {
                html += data['result'][0]['error_result_html'];
            }
            html += '</tr>';
            $(data['context'])
            .replaceWith(html);
        })
        .on('fileuploadfail', function (e, data) {
            $(data['context']).find('.name')
            .html('There was a server problem while attempting the upload, please try again later.');
            totalRows = getTotalRows();
            if (totalRows > 0) {
                totalRows = totalRows - 1;
            }
            updateTotalFilesText(totalRows);
        });
        $('#fileUpload #fileupload #files a:not([target^=_blank])').on('click', function (e) {
            e.preventDefault();
            $('<iframe style="display:none;"></iframe>')
            .prop('src', this.href)
            .appendTo('body');
        });
        $('.showAdditionalOptionsLink').click(function (e) {
            showAdditionalOptions();
            e.preventDefault();
            return false;
        });
});
$(function () {
    $("#tabs").tabs();
    $("#tabs").mouseover(function () {
        $("#tabs").addClass("tabsHover");
    });
    $("#tabs").mouseout(function () {
        $("#tabs").removeClass("tabsHover");
    });
});
/* ============================================================================ */
/* ============================================================================ */
function findUrls(text) {
    var source = (text || '').toString();
    var urlArray = [];
    // var url; Never Used
    var matchArray;
    var regexToken = /(((ftp|https?):\/\/)[\-\w@:%_\+.~#?,&\/\/=]+)|((mailto:)?[_.\w-]+@([\w][\w\-]+\.)+[a-zA-Z]{2,3})/g;
    while ((matchArray = regexToken.exec(source)) !== null) {
        var token = matchArray[0];
        urlArray.push(token);
    }
    return urlArray;
}
/* NOTE:!!!!! Never used  */
function urlUploadFiles() {
    var urlList = $('#urlList').val();
    if (urlList.length === 0) {
        alert('Please enter the urls to start.');
        return false;
    }
    urlList = findUrls(urlList);
    if (urlList.length === 0) {
        alert('No valid urls found, please make sure any start with http or https andtry again.');
        return false;
    }
    if (urlList.length > 5 ) {
        alert('You can not add more than[[[MAX_URLS]]] urls at once.');
        return false;
    }
    var html = '';
    var i;
    for (i = 0; i < urlList.length; ++i) {
        html += '<tr id="rowId' + i + '"><td class="cancel"><a href="#" onClick="return false;"><img src="http://cdn.chillingsafe.com/images/processing_small.gif" class="processingIcon" height="16" width="16" />';
        html += '</a></td><td class="name" colspan="3">' + urlList[i] + '</td></tr>';
    }
    $('#urlUpload #urls').html(html);
    $('#urlUpload #urlFileListingWrapper').removeClass('hidden');
    $('#urlUpload #urlFileUploader').addClass('hidden');
    $('#urlUpload #fileUploadBadge').addClass('hidden');
    function doRequest(url, i) {
        var request = $.ajax({
            url: "http://chillingsafe.com/upload_url",
            type: "POST",
            data: {
                url: url,
                rowId: i
            },
            dataType: "json",
            ysrowId: i,
            xhrFields: {
                withCredentials: true
            }
        });
        request.done(function (data) {
            var isSuccess = true;
            if (data.error !== null) {
                isSuccess = false;
            }
            var html = '';
            html += '<tr class="template-download';
            if (isSuccess === false) {
                html += ' errorText';
            }
            html += '" onClick="">';
            if (isSuccess === false) {
                html += data.error_result_html;
            } else {
                html += data.success_result_html;
                fileUrls.push(data.url);
                fileDeleteHashes.push(data.delete_hash);
                fileShortUrls.push(data.short_url);
            }
            html += '</tr>';
            $('#rowId' + data.rowId).replaceWith(html);
            if (i == urlList.length - 1) {
                $('#urlUpload .fileSectionFooterText').removeClass('hidden');
                sendAdditionalOptions();
                setupCopyAllLink();
            }
        });
        request.fail(function(/*jqXHR, textStatus*/) {
            $('#rowId' + this.ysrowId + ' .cancel .processingIcon').attr('src', 'http://cdn.chillingsafe.com/images/red_error_small.png');
            $('#rowId' + this.ysrowId + ' .name').html(urlList[this.ysrowId] + ' (Failed to request file, possible ajax issue)');
        });

    }
    for (i = 0; i < urlList.length; ++i) {
        doRequest(urlList[i], i);
    }
}
/* ============================================================================ */
/* ============================================================================ */
function CheckTables() {
    $("table ").each(function (/*index*/) {
        $(this).find('tbody:not(:empty)').parent().show();
        $(this).find('tbody:empty').parent().hide();
    });
}
setInterval(CheckTables, 100);
/* ============================================================================ */
/* ============================================================================ */
/* ============================================================================ */
Community
  • 1
  • 1
user13500
  • 3,817
  • 2
  • 26
  • 33
  • Thank you for the code but there is some php included with the js and I have edited the main post now to display all. – joedm Mar 16 '14 at 16:02
  • @user3425749: You might find it helpful pasting you JS code here: http://www.jshint.com/ Ideally use some plugin to have your code hinted all the time. Personally I use it in Vim something like this: http://technotales.wordpress.com/2011/05/21/node-jslint-and-vim/ – user13500 Mar 16 '14 at 16:08
  • Yes thanks I will use this, and I could not add the code to the post so I made it into a txt file http://chillingsafe.com/upload.txt – joedm Mar 16 '14 at 16:10
  • I have had a look and found these problems.Six warnings 1 Expected an identifier and instead saw '<'. 1 Expected an assignment or function call and instead saw an expression. 1 Missing semicolon. 2 Expected an identifier and instead saw 'var'. 2 Unrecoverable syntax error. (0% scanned). One undefined variable 1 script – joedm Mar 16 '14 at 16:26
  • @user3425749: It doesn't handle PHP code. If your script has PHP code it will try to interpret it as Javascript. *instead saw '<'.* is typically for your PHP opening tags. If it is a JS error it is usually better to look at the client side result. Put it trough here: http://jsbeautifier.org/ if your editor doesn't indent properly. – user13500 Mar 16 '14 at 16:27
  • @user3425749: Also add the comment I have at top to suppress some of the warnings. Note that a warning is not an error, but a recommendation from the coders of the tool. – user13500 Mar 16 '14 at 16:35
  • Do you know what could be causing Chrome to display this error when every other browser is fine? Uncaught TypeError: Cannot read property 'innerHTML' of null. When on broadband it is fine on Chrome, it is only over a 3g network when the network injects that script to save data usage. – joedm Mar 16 '14 at 16:49
  • I have put the last function in the wrap and changed ready to load but it seems to have still left the error and cause the uploader to look like this http://i.stack.imgur.com/fbZS6.png – joedm Mar 16 '14 at 17:15
  • @user3425749: Where is the error reported? I assume you do not have any console, or? – user13500 Mar 16 '14 at 17:20
  • I am using the built-in console on Google Chrome – joedm Mar 16 '14 at 17:32
  • @user3425749: Comparing your image to the rendered page in a normal browser it looks like the issue is with the template thing: `text/x-jquery-tmpl`. That part is perhaps executed to early. (Note: I have no clue on such templates, they scares me.) – user13500 Mar 16 '14 at 17:32
  • @user3425749: Regarding your comment on console (Thought you was on a device with no console in the browser.) : Doesn't it give you a line-number etc. with the error? As in can't you click the error to go to where it originated? – user13500 Mar 16 '14 at 17:33
  • Yes here http://cdn.chillingsafe.com/scripts/jquery.tmpl.min.js it says line 10 and I know it has something specifically to do with getElementById(a). – joedm Mar 16 '14 at 17:38
  • @user3425749: Yes, and that is the *template thing*. Can you include the `jquery.tmpl.min.js` file below the `text/x-jquery-tmpl` scripts? – user13500 Mar 16 '14 at 17:45
  • Yes the error goes away but the uploader stops working completely. – joedm Mar 16 '14 at 17:51
  • @user3425749: Err. Have no clue on that template thing and how it works. But guess it rely on the plugin being loaded before the `text/x-jquery-tmpl` script then. But looking at this Q/A http://stackoverflow.com/q/11527693/3278057 it could be that, for some reason, the `text/x-jquery-tmpl` scripts are not present when run, out of order or something else. (As you have them both.) – user13500 Mar 16 '14 at 18:09
  • @user3425749: Could you try to change type to `text/x-tmpl` instead of `text/x-jquery-tmpl` ? – user13500 Mar 16 '14 at 18:13
  • @user3425749: Try moving all script includes an all your scripts to the bottom of the page. (Or at least below the `text/x-jquery-tmpl` scripts.) As in: every `` blocks. – user13500 Mar 16 '14 at 18:17
  • @user3425749: Looking at the source of this page: http://blueimp.github.io/jQuery-File-Upload/ that is how it is done there, so should be OK to include *after* the `text/x-jquery-tmpl` scripts. – user13500 Mar 16 '14 at 18:18
  • Okay so the error has now gone which is good but it has been replaced with Uncaught ReferenceError: $ is not defined – joedm Mar 16 '14 at 18:25
  • @user3425749: Then you have your includes out of order. You need to include `jquery` first. – user13500 Mar 16 '14 at 18:29
  • I have edited my original post to show the order I have the in currently, I have tried to change them around but I am unsure on the correct order. And yes this has been very helpful and I would definitely upvote if I could but I do not have enough rep points. This will undoubtedly be getting best answer though, I'm very grateful for all the help. – joedm Mar 16 '14 at 18:40
  • @user3425749: Perhaps I was unclear on this, but you include them *before* the script parts? Your resulting file should be something like this: http://pastebin.com/VcAyNVW8 – user13500 Mar 16 '14 at 18:45
  • @user3425749: Also note that you could also possibly use PHP `header("Cache-Control: no-transform");` as noted here: http://stackoverflow.com/a/6229924/3278057 , at least in a debugging phase. – user13500 Mar 16 '14 at 18:54
  • I see now, I have changed them but now I have the dreaded Uncaught TypeError: Cannot read property 'innerHTML' of null error again. Last time I looked around for a answer I found out the reason you get this is because an id is not defined, the id is the one in line 10 of jquery.tmpl.min.js but I do not understand why it is defined in all browsers except for Chrome. – joedm Mar 16 '14 at 18:56
  • @user3425749: Does it happen when you add `no-transform` ? And yes, it is complaining about missing element. You could include a local copy of the `jquery.tmpl.min.js` file and add something like: `console.log("TEMPLATE GETTING ID:", a);` on on the line before the `getElementById` line. Something like this: http://pastebin.com/p5vpAdAF , then check which ID it fails on by looking at the log. – user13500 Mar 16 '14 at 19:02
  • I have found that the ids are template-upload and template-download. – joedm Mar 16 '14 at 19:11
  • @user3425749: Yes, that sounds correct. Or, that is: as they are added before your scripts *and* you use `$().ready(` they ***should*** be there. I'm at a loss. Recommend you try to make a minimal example. I.e. only the template scripts and check if that works. – user13500 Mar 16 '14 at 19:36
  • It is really strange, I still feel it has something to do with the injected code, script src="http://1.2.3.8/bmi-int-js/bmi.js" language="javascript". This only happens on google Chrome over 3g connection. If you go to the upload page and reload using shift and f5 a few times the code is not injected and it works fine. I'll definitely try that and get back to you. – joedm Mar 16 '14 at 19:58
  • @user3425749: I do not have access to that script, but hope you find a solution. Sounds like a whacky problem. In a debug attempt you could also try to sabotage it as explained here: http://stackoverflow.com/a/4113511/3278057 – user13500 Mar 16 '14 at 20:08
  • I am now 100% sure the problem is that script, looking at view source from both IE and Chrome you can see a huge difference. If you see this screenshot http://i.stack.imgur.com/xOve3.png only Chrome injects the script. Is there any way to prevent it from doing this? And thanks for the link. – joedm Mar 16 '14 at 20:14
  • @user3425749: Err. You have a `

    ` tag at top of your page ... That could cause issues.

    – user13500 Mar 16 '14 at 20:25
  • Yes haha I realized, that happened when copying the scripts to place them at the bottom of the page, must have accidentally brought that up too with them. Here is a screenshot of the page on my home broadband without connecting to 3G, http://i.stack.imgur.com/koeIS.png now it works perfect so its definitely their "optimizing" that is breaking the script, but I'm not sure it would affect to many people as it only happens on Chrome whilst on a few mobile networks. Thanks for all your help today, much appreciate it :). – joedm Mar 16 '14 at 20:31
  • @user3425749: np :), And as mentioned earlier, using `header("Cache-Control: no-transform");` should prevent it, but *should* in this case depends on service provider. As for what get mangled to not work you would need to post the code as it is when corrupted. A copy of the bmi.js file could also help. – user13500 Mar 16 '14 at 20:38
  • @user3425749: Yes, but that server isn't accessible unless you do it trough a provider serving it. I can't access it. Further the mangling of the markup/HTLM is done by some proxy and not the JS. – user13500 Mar 16 '14 at 20:54
  • Yes I fully understand, I think for now it should be okay and I will only start worrying about it if lots of users have the problem :) – joedm Mar 16 '14 at 21:02