11

I've update Chrome on version 83, and some of my forms that use an "Ajax upload" component (more info below) aren't working. I've read the issues of the new version (https://developers.google.com/web/updates/2020/05/nic83) but I can't find anything related on forms, iframes, files, ajax or posts.

I'll try to post a sample on fiddler, but I want to know if somebody knows anything about it.

By other way, on other forms I've a multifile, drag&drop uploader (dropzone.js) and it's working fine, but it isn't easy to convert and I need a fast solution.

A dummy sample (I don't have any sandbox to test upload): https://jsfiddle.net/drvespa/7ue8k94r/3/

  • On Chrome 83 (I've tried on Canary 85 version too): it throws no error cause the submit of the form isn't catched by AjaxUpload component. The callback is being called before the submit is done, and the response is empty.
  • On Firefox: it throws an error cause AjaxUpload component is trying to deserialize 404 of the dummy upload page.

I post the library on https://filebin.net/8sgsmq7sh14m0qen:

/**
* Ajax upload
* Project page - http://valums.com/ajax-upload/
* Copyright (c) 2008 Andris Valums, http://valums.com
* Licensed under the MIT license (http://valums.com/mit-license/)
* Version 3.6 (26.06.2009)
*/
Marc
  • 1,359
  • 1
  • 15
  • 39
  • The solutions described here didn't work for me at the time I am writing this. It seems the whele thing was because of a chrome issue which was fixed. So the soutions here only were good while chrome had the issue. Now, chrome has fixed the issue and these solutions no longer work. More details here: https://stackoverflow.com/questions/62022757/ajaxfileupload-is-not-woking-in-latest-version-of-chrome-version-83-0-4103-61/62183097#62183097 – Gabriel Jun 25 '20 at 15:33
  • I've tested them now in version 83.0.4103.106 and effectively, the issue has been solved, but the code in the accepted answer is working for me too, so I didn't go back. – Marc Jun 26 '20 at 06:25
  • My bad. I meant the second solution is not working anymore. Sorry for the confusion. Thanks for the feedback. – Gabriel Jun 27 '20 at 13:07

5 Answers5

12

The problem is that the library is creating an <iframe>, with an src attribute, and listens for the load event of that iframe right after it did.

/**
* Creates iframe with unique name
*/
_createIframe: function () {
    // unique name
    // We cannot use getTime, because it sometimes return
    // same value in safari :(
    var id = getUID();

    // Remove ie6 "This page contains both secure and nonsecure items" prompt 

    var iframe = toElement('<iframe src="javascript:false;" name="' + id + '" />');
    iframe.id = id;
    iframe.style.display = 'none';
    d.body.appendChild(iframe);
    return iframe;
},

then in submit method

            var iframe = this._createIframe();

            // some synchronous operations

            addEvent(iframe, 'load', function (e) { // ...

Since this iframe has an src attribute, Chrome will start its loading, and since its src is a fake url, this operation actually is resolved synchronously, meaning that the load event is already set to fire at the next event-loop iteration.

const frame = document.createElement('iframe');
frame.src = 'javascript:return false';
document.body.append(frame);
frame.addEventListener('load', (evt) => console.log('loaded', frame.src) );

setTimeout( () => frame.src = "about:blank", 0 );

// Results in Chrome:
// loaded javascript:return false
// loaded about:blank

// Results in Firefox:
// loaded about:blank

So the one load event this library is receiving is that initial load event, of an empty document, and not the one of the real request.

To fix that, all you need is to remove this src="javascript:false;" from the library code: https://jsfiddle.net/9phxmqjw/

Kaiido
  • 123,334
  • 13
  • 219
  • 285
  • Great! It was a trick to work in IE6! I would remove IE6 from compatible browsers! haha! – Marc May 26 '20 at 05:59
3

I just set srcdoc attribute to iframe equals url in AjaxUpload component.

iframe.setAttribute('srcdoc', this._settings.action);

It's solved my problem.

Function into file AjaxUpload.js:

        _createIframe: function(){
            var id = getUID();            

            var iframe = toElement('<iframe src="javascript:false;" name="' + id + '" />');        
            iframe.setAttribute('id', id);
            iframe.setAttribute('srcdoc', this._settings.action);

            iframe.style.display = 'none';
            document.body.appendChild(iframe);

            return iframe;
        }
1

This answer helped me patch our copy of Atmail so uploading attachments works again in Chrome 83 - thanks!

The above setAttribute line should be inserted into the AjaxUpload.js file, inside the '_createIframe' function. I put it immediately below the setAttribute('id', id) call and that has done the trick :)

Ender
  • 11
  • 1
0

We were using this old plugin:

http://jquery.malsup.com/form/#options-object

There's an option there you might be using if you were supporting ie8 at some point in the past 10 years...

{
    url: '/branded/image_upload',
    type: 'POST',
    iframe: false
}

We also had a <textarea></textarea> wrapper hack in the response.

This code was passed down through a lot of iterations lol.

Throttlehead
  • 1,927
  • 6
  • 22
  • 36
0

Thank You! Also, for all still using Opencart 1.5 after this Chrome Update, image and document upload is fixed by adding:

iframe.setAttribute('srcdoc', this._settings.action);

in \admin\view\javascript\jquery\ajaxupload.js

var iframe = toElement('<iframe src="javascript:false;" name="' + id + '" />');
            // src="javascript:false; was added
            // because it possibly removes ie6 prompt 
            // "This page contains both secure and nonsecure items"
            // Anyway, it doesn't do any harm.
            iframe.setAttribute('id', id);
            iframe.setAttribute('srcdoc', this._settings.action);
            iframe.style.display = 'none';
            document.body.appendChild(iframe);
OliverS
  • 1
  • 1
  • This solution worked for a while for us and then it stoped working. Any ideas why? Can you comment why did you decide to add that? What's the reasoning behind it? – Gabriel Jun 25 '20 at 14:43