我尝试允许用户上传文件而不会在上传文件时导致页面更改。为此,我使用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()
。
知道这里可能会发生什么吗?
答案 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中运行。