假设我在页面上有这个元素:
<input id="image-file" type="file" />
这将创建一个按钮,允许网页用户通过浏览器中操作系统的“文件打开...”对话框选择文件。
假设用户单击所述按钮,在对话框中选择一个文件,然后单击“确定”按钮关闭对话框。
所选文件名现在存储在:
document.getElementById("image-file").value
现在,假设服务器在 URL“/upload/image”处处理多部分 POST。
如何将文件发送到“/upload/image”?
另外,如何监听文件上传完成的通知?
Pure JS
您可以使用fetch https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API可选地使用await-try-catch
let photo = document.getElementById("image-file").files[0];
let formData = new FormData();
formData.append("photo", photo);
fetch('/upload/image', {method: "POST", body: formData});
async function SavePhoto(inp)
{
let user = { name:'john', age:34 };
let formData = new FormData();
let photo = inp.files[0];
formData.append("photo", photo);
formData.append("user", JSON.stringify(user));
const ctrl = new AbortController() // timeout
setTimeout(() => ctrl.abort(), 5000);
try {
let r = await fetch('/upload/image',
{method: "POST", body: formData, signal: ctrl.signal});
console.log('HTTP response code:',r.status);
} catch(e) {
console.log('Huston we have problem...:', e);
}
}
<input id="image-file" type="file" onchange="SavePhoto(this)" >
<br><br>
Before selecting the file open chrome console > network tab to see the request details.
<br><br>
<small>Because in this example we send request to https://stacksnippets.net/upload/image the response code will be 404 ofcourse...</small>
<br><br>
(in stack overflow snippets there is problem with error handling, however in <a href="https://jsfiddle.net/Lamik/b8ed5x3y/5/">jsfiddle version</a> for 404 errors 4xx/5xx are <a href="https://stackoverflow.com/a/33355142/860099">not throwing</a> at all but we can read response status which contains code)
老派方法 - xhr
let photo = document.getElementById("image-file").files[0]; // file from input
let req = new XMLHttpRequest();
let formData = new FormData();
formData.append("photo", photo);
req.open("POST", '/upload/image');
req.send(formData);
function SavePhoto(e)
{
let user = { name:'john', age:34 };
let xhr = new XMLHttpRequest();
let formData = new FormData();
let photo = e.files[0];
formData.append("user", JSON.stringify(user));
formData.append("photo", photo);
xhr.onreadystatechange = state => { console.log(xhr.status); } // err handling
xhr.timeout = 5000;
xhr.open("POST", '/upload/image');
xhr.send(formData);
}
<input id="image-file" type="file" onchange="SavePhoto(this)" >
<br><br>
Choose file and open chrome console > network tab to see the request details.
<br><br>
<small>Because in this example we send request to https://stacksnippets.net/upload/image the response code will be 404 ofcourse...</small>
<br><br>
(the stack overflow snippets, has some problem with error handling - the xhr.status is zero (instead of 404) which is similar to situation when we run script from file on <a href="https://stackoverflow.com/a/10173639/860099">local disc</a> - so I provide also js fiddle version which shows proper http error code <a href="https://jsfiddle.net/Lamik/k6jtq3uh/2/">here</a>)
SUMMARY
- 在服务器端,您可以读取原始文件名(和其他信息),该文件名会自动包含在浏览器的请求中
filename
表单数据参数。
- 您不需要设置请求标头
Content-Type
to multipart/form-data
- 这将由浏览器自动设置(其中包括强制性的boundary范围 https://stackoverflow.com/questions/3508338/what-is-the-boundary-in-multipart-form-data).
- 代替
/upload/image
您可以使用完整地址,例如http://.../upload/image
(当然,这两个地址都是任意的,并且取决于服务器 - 并且参数的情况相同method
- 通常在服务器上“POST”用于文件上传,但有时可以使用“PUT”或其他)。
- 如果您想在单个请求中发送多个文件,请使用
multiple
属性:<input multiple type=... />
,并以类似的方式将所有选定的文件附加到 formData(例如photo2=...files[2];
... formData.append("photo2", photo2);
)
- 您可以包含附加数据 (json) 来请求,例如
let user = {name:'john', age:34}
这样:formData.append("user", JSON.stringify(user));
- 您可以设置超时:for
fetch
using AbortController
,对于旧方法xhr.timeout= milisec
- 该解决方案应该适用于所有主要浏览器。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)