Chrome 83: Cannot upload file

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 :)


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;
        }

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/