【问题标题】:NS_ERROR_UNEXPECTED in Firefox when uploading file from iframe从 iframe 上传文件时 Firefox 中的 NS_ERROR_UNEXPECTED
【发布时间】:2015-10-01 08:40:37
【问题描述】:

我正在尝试允许用户上传文件,而不会在他们上传文件时导致页面发生变化。为此,我使用了一个 iframe,我在其中添加了一个表单和一个文件输入,然后在(隐藏的)iframe 中提交表单。这在 Chrome 上运行得很好,但在 Firefox 上却不行。

以下是导致此问题的代码。

<!DOCTYPE html>
<html>
    <head>
        <style>
            #pretty-button { background: blue; }
            #hidden-uploader { display: none; }
        </style>
        <script>
        window.addEventListener('DOMContentLoaded', function() {
            var btn = document.getElementById('pretty-button');
            var filename_output = document.getElementById('filename');
            var upload_iframe = document.getElementById('hidden-uploader');

            btn.addEventListener('click', function() {
                document.body.appendChild(upload_iframe);
                _document = upload_iframe.contentDocument;

                var form = _document.createElement('form');
                form.setAttribute('method', 'post');
                form.setAttribute('enctype', 'multipart/form-data');
                form.setAttribute('action', '.');

                var file_input = _document.createElement('input');
                file_input.setAttribute('type', 'file');
                file_input.setAttribute('name', 'document');

                form.appendChild(file_input);
                _document.body.appendChild(form);
                file_input.click();

                file_input.addEventListener('change', function() {
                    console.log('file selected');
                    form.submit();
                    upload_iframe.addEventListener('load', function() {
                        console.log('file uploaded');
                    });
                });

            });
        });
        </script>
    </head>
    <body>
        <button id="pretty-button">Choose a File</button>
        <span id="filename"></span>
        <iframe id="hidden-uploader"></iframe>
    </body>
</html>

On firefox, this fails with NS_ERROR_UNEXPECTED: on line 33, which is form.submit(), when a file is selected.

知道这里会发生什么吗?

【问题讨论】:

    标签: javascript html firefox iframe


    【解决方案1】:

    我想我发现了问题所在

    document.body.appendChild(upload_iframe);
    

    这会导致 iframe 重新加载自己,这意味着 iframe 重新附加到文档正文之前的 contentDocument 与重新附加到文档正文后的 iframe 的 contentDocument 不同。文件对话框打开时会重新加载。

    这可以通过进行以下更改来验证:

    <!DOCTYPE html>
    <html>
        <head>
            <style>
                #pretty-button { background: blue; }
                #hidden-uploader { display: none; }
            </style>
            <script>
            window.addEventListener('DOMContentLoaded', function() {
                var btn = document.getElementById('pretty-button');
                var filename_output = document.getElementById('filename');
                var upload_iframe = document.getElementById('hidden-uploader');
    
                btn.addEventListener('click', function() {
                    document.body.appendChild(upload_iframe);
                    _document = upload_iframe.contentDocument;
    
                    var form = _document.createElement('form');
                    form.setAttribute('method', 'post');
                    form.setAttribute('enctype', 'multipart/form-data');
                    form.setAttribute('action', '.');
    
                    var file_input = _document.createElement('input');
                    file_input.setAttribute('type', 'file');
                    file_input.setAttribute('name', 'document');
    
                    form.appendChild(file_input);
                    _document.body.appendChild(form);
                    file_input.click();
                    // So far, the iframe hasn't reloaded.
    
                    file_input.addEventListener('change', function() {
                        /* Because the iframe loads in less time than it 
                         * takes for the user to select a file, the iframe
                         * has now reloaded, and _document refers to the 
                         * contentDocument of an iframe which is no longer
                         * attached to the page.
                         */
                        console.log('file selected');
                        var _newDocument = upload_iframe.contentDocument;
                        console.log(_document === _newDocument); // false in Firefox, true in Chrome
                        form.submit();
                        upload_iframe.addEventListener('load', function() {
                            console.log('file uploaded');
                        });
                    });
    
                });
            });
            </script>
        </head>
        <body>
            <button id="pretty-button">Choose a File</button>
            <span id="filename"></span>
            <iframe id="hidden-uploader"></iframe>
        </body>
    </html>
    

    通过删除违规行,上述内容开始在 Firefox 中运行。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-10-27
      • 1970-01-01
      • 1970-01-01
      • 2011-10-09
      • 2015-12-01
      • 1970-01-01
      • 1970-01-01
      • 2011-12-16
      相关资源
      最近更新 更多