从iframe上传文件时,在Firefox中使用NS_ERROR_UNEXPECTED

时间:2015-07-13 07:11:11

标签: javascript html firefox iframe

我尝试允许用户上传文件而不会在上传文件时导致页面更改。为此,我使用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>

在firefox上,当选择文件时,第33行的NS_ERROR_UNEXPECTED:失败,这是form.submit()

知道这里可能会发生什么吗?

1 个答案:

答案 0 :(得分:0)

我想我想出了问题,就在

document.body.appendChild(upload_iframe);

这会导致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中运行。