JavaScript: 上传文件

31 浏览
0 Comments

JavaScript: 上传文件

假设在页面上有这个元素:


这将创建一个按钮,允许网页用户通过浏览器中的操作系统“文件打开…”对话框选择文件。

假设用户点击该按钮,在对话框中选择一个文件,然后点击“确定”按钮关闭对话框。

选择的文件名现在存储在:

document.getElementById("image-file").value

现在,假设服务器在URL“/upload/image”处处理多部分POST。

如何将文件发送到“/upload/image”?

另外,如何监听文件上传完成的通知?

admin 更改状态以发布 2023年5月23日
0
0 Comments

如果你不是要使用ajax上传文件,只需将表单提交到/upload/image

如果你想在后台上传图片(例如,不提交整个表单),你可以使用ajax:

0
0 Comments

纯JS

你可以使用fetch与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);
    }
}




Before selecting the file open chrome console > network tab to see the request details.

Because in this example we send request to https://stacksnippets.net/upload/image the response code will be 404 ofcourse...

(in stack overflow snippets there is problem with error handling, however in jsfiddle version for 404 errors 4xx/5xx are not throwing 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);
}




Choose file and open chrome console > network tab to see the request details.

Because in this example we send request to https://stacksnippets.net/upload/image the response code will be 404 ofcourse...

(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 local disc - so I provide also js fiddle version which shows proper http error code here)

总结

  • 在服务器端,您可以读取浏览器自动包含在formData参数“filename”中的原始文件名(和其他信息)。
  • 您不需要将请求头“Content-Type”设置为“multipart/form-data” - 浏览器将自动设置此设置(其中将包含必填的“boundary”参数)。
  • 您可以使用完整地址,例如http://… /upload/image(当然,这两个地址都是任意的,并且取决于服务器 - 对于参数方法也是同样的情况-通常使用“POST”用于文件上传,但有时可能使用“PUT”或其他方式)。
  • 如果您想在单个请求中发送多个文件,请使用multiple属性:,并以类似的方式附加所有选择的文件到formData中(例如photo2 = ... files [2]; ... formData.append(“photo2”,photo2);
  • 您可以以这种方式将附加数据(json)包括在请求中,例如let user = {name:'john', age:34}formData.append(“user”,JSON.stringify(user));
  • 您可以使用AbortControllerfetch设置超时,也可以使用xhr.timeout = milisec 为旧方法设置超时。
  • 这些解决方案应适用于所有主流浏览器。
0