【问题标题】:Chrome 83: Cannot upload fileChrome 83:无法上传文件
【发布时间】:2020-09-12 07:18:30
【问题描述】:

我已经在 83 版上更新了 Chrome,但我的一些使用“Ajax 上传”组件的表单(下面有更多信息)无法正常工作。我已经阅读了新版本 (https://developers.google.com/web/updates/2020/05/nic83) 的问题,但我找不到与表单、iframe、文件、ajax 或帖子相关的任何内容。

我会尝试在 fiddler 上发布一个示例,但我想知道是否有人对此有所了解。

通过其他方式,在其他表单上,我有一个多文件拖放上传器 (dropzone.js),它工作正常,但它不容易转换,我需要一个快速的解决方案。

一个虚拟样本(我没有任何沙箱来测试上传):https://jsfiddle.net/drvespa/7ue8k94r/3/

  • 在 Chrome 83 上(我也在 Canary 85 版本上尝试过):它不会引发错误,因为 AjaxUpload 组件未捕获表单的提交。在提交完成之前调用回调,响应为空。
  • 在 Firefox 上:它会引发错误,因为 AjaxUpload 组件正在尝试反序列化虚拟上传页面的 404。

我在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)
*/

【问题讨论】:

  • 在我写这篇文章的时候,这里描述的解决方案对我不起作用。这似乎是因为修复了 chrome 问题。因此,只有当 chrome 出现问题时,这里的解决方案才有效。现在,chrome 已经解决了这个问题,这些解决方案不再起作用。更多细节在这里:stackoverflow.com/questions/62022757/…
  • 我现在已经在 83.0.4103.106 版本中对它们进行了测试,并且有效地解决了问题,但是接受的答案中的代码也对我有用,所以我没有回去。
  • 我的错。我的意思是第二种解决方案不再起作用。对困惑感到抱歉。感谢您的反馈。

标签: javascript ajax google-chrome


【解决方案1】:

问题是库正在创建一个带有src 属性的

/**
* 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;
},

然后在submit方法中

            var iframe = this._createIframe();

            // some synchronous operations

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

由于这个 iframe 有一个src 属性,Chrome 会开始加载它,由于它的src 是一个假的 url,这个操作实际上是同步解析的,这意味着加载事件已经设置为在下一个触发事件循环迭代。

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

所以这个库接收到的一个load 事件是一个空文档的初始加载事件,而不是真正的请求。

要解决此问题,您只需从库代码中删除此 src="javascript:false;"https://jsfiddle.net/9phxmqjw/

【讨论】:

  • 太棒了!在 IE6 中工作是一个技巧!我会从兼容的浏览器中删除 IE6!哈哈!
【解决方案2】:

我只是在 AjaxUpload 组件中将 srcdoc 属性设置为 iframe 等于 url

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

它解决了我的问题。

函数写入文件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;
        }

【讨论】:

  • 您能发布一个完整的解决方案作为答案吗?也许你分叉小提琴并发布工作示例。现在还不清楚你把你的代码行放在哪里......
  • 此解决方案为我们工作了一段时间,然后停止工作。任何想法为什么?
  • 你能评论一下你为什么决定添加它吗?背后的原因是什么?
  • 你需要使用这个解决方案stackoverflow.com/a/62015090/13258327。没错。
【解决方案3】:

这个答案帮助我修补了我们的 Atmail 副本,以便在 Chrome 83 中再次上传附件 - 谢谢!

上面的 setAttribute 行应该被插入到 AjaxUpload.js 文件的 '_createIframe' 函数中。我把它放在 setAttribute('id', id) 调用的正下方,这就成功了:)

【讨论】:

    【解决方案4】:

    我们使用的是这个旧插件:

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

    如果您在过去 10 年的某个时间点支持 ie8,那么您可能会使用一个选项...

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

    我们在响应中也有一个&lt;textarea&gt;&lt;/textarea&gt; 包装黑客。

    这段代码是通过大量迭代传递下来的,哈哈。

    【讨论】:

      【解决方案5】:

      谢谢!此外,对于在此 Chrome 更新后仍在使用 Opencart 1.5 的所有人,通过添加以下内容来修复图像和文档上传:

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

      在 \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);
      

      【讨论】:

      • 此解决方案为我们工作了一段时间,然后停止工作。任何想法为什么?你能评论一下你为什么决定添加它吗?背后的原因是什么?
      猜你喜欢
      • 2018-12-30
      • 2020-04-16
      • 1970-01-01
      • 2020-09-30
      • 2016-08-22
      • 1970-01-01
      • 2016-05-15
      • 2020-09-23
      相关资源
      最近更新 更多