我有一个简单的表单来上传同步运行良好的文件:
<form id="uploadForm" action="/upload" method="post" encType="multipart/form-data">
<input type="file" id="file" name="file" accept=".csv" />
<input type="text" name="comment" />
<button type="submit">Upload</button>
</form>
如何让这个表单异步上传文件(不重新加载页面?),并在上传完成时收到通知,如果有任何错误?
我知道发出异步请求的主要方法是使用XMLHttpRequest
,我发现现在可以使用以下内容(我没有测试过这段代码):
function handleLoad() {
console.log(this.responseText);
}
function handleError(error) {
console.error(error.stack);
}
function handleSubmit(e) {
e.preventDefault();
var form = document.getElementById('uploadForm');
var request = new XMLHttpRequest();
request.addEventListener('load', handleLoad);
request.addEventListener('error', handleError);
request.open("POST", "/upload");
request.send(new FormData(form));
}
但是according to MDN,仅在IE10 +中支持发送FormData
,Blob
,File
或ArrayBuffer
,我想要向后兼容的解决方案(不使用jQuery)。
How can I upload files asynchronously?有很多答案,但到目前为止我读过的所有答案都使用jQuery或使用我上面描述的现代XMLHttpRequest方法。
我正在使用React,并且对jQuery提供的任何其他内容都没有用处,所以我想通过使用vanilla JS来解决这个问题,让我的页面下载量更小。
答案 0 :(得分:-1)
最早建立的方法是将<form>
目标设为隐藏<iframe>
元素,方法是将target="<name of iframe>"
添加到<form>
元素。当您在JavaScript中调用form.submit()
时,它会在目标<iframe>
中加载响应:
<form id="uploadForm" action="/upload" method="post" encType="multipart/form-data" target="asyncFrame">
<iframe id="asyncFrame" name="asyncFrame" height="0" width="0" frameborder="0"></iframe>
<input type="file" id="file" name="file" accept=".csv" />
<input type="text" name="comment" />
<button type="submit">Upload</button>
</form>
<script>
var iframe = document.getElementById('asyncFrame');
function handleLoad() {
console.log('response:', iframe.contentWindow.document.body.innerText);
}
iframe.addEventListener('load', handleLoad);
</script>
这种方法最尴尬的是无法获取响应的状态代码,并且没有标准方式(据我所知)来确定请求是否失败。您必须检查响应正文(iframe.contentWindow.document.body.innerText
)以确定是否存在错误(如果您要发布到自己的服务器,幸运的是,您可以确保响应正文包含足够的信息,但如果它是第三方服务器,你可能运气不好。)