JavaScript:上传文件

IT技术 javascript file-upload
2021-01-28 14:01:17

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

<input id="image-file" type="file" />

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

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

所选文件名现在存储在:

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

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

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

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

3个回答

纯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});

老派方法 - 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);

概括

  • 在服务器端,您可以读取原始文件名(和其他信息),它会自动包含在浏览器的filenameformData 参数中请求
  • 您不需要将请求标头设置Content-Typemultipart/form-data- 这将由浏览器自动设置(将包括强制boundary参数)。
  • 而不是/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));
  • 您可以设置超时:用于fetch使用AbortController,对于旧方法xhr.timeout= milisec
  • 此解决方案应该适用于所有主要浏览器。
@HidaytRahman 这个错误通常在服务器没有为你的 url 实现 POST 方法时出现
2021-03-22 14:01:17
我收到错误 net::ERR_ABORTED 405 (Method Not Allowed)
2021-03-25 14:01:17
奇怪 - 根据您的标题,我认为我们不再需要服务器:D
2021-03-28 14:01:17
formData === 表单提交 enctype="multipart/form-data"
2021-03-29 14:01:17
我得到POST http://localhost:8000/upload/image 404 (Not Found). 在我的 React Node 测试项目中的 /src 和 /public 下创建了 /upload/image。
2021-04-06 14:01:17

除非您尝试使用 ajax 上传文件,否则只需将表单提交/upload/image.

<form enctype="multipart/form-data" action="/upload/image" method="post">
    <input id="image-file" type="file" />
</form>

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

或 iframe 0x0 大小,在其 src="" 内带有图像上传脚本,并使用 target="iframeId" 将结果发布给它,在 iframe src .load 事件上读取结果,例如可以使用 jQuery 绑定。
2021-03-18 14:01:17
现在实际上可以通过 Javascript 和 Ajax 进行投票,请参阅:stackoverflow.com/a/10811427/694469 (我没有投票)。
2021-03-18 14:01:17
@KajMagnus,您的意思可能是“上传”但不小心说的是“投票”
2021-03-26 14:01:17

我已经尝试这样做了一段时间,但这些答案都不适合我。我就是这样做的。

我有一个选择文件和一个提交按钮

<input type="file" name="file" id="file">
<button onclick="doupload()" name="submit">Upload File</button>

然后在我的 javascript 代码中我把这个

function doupload() {
    let data = document.getElementById("file").files[0];
    let entry = document.getElementById("file").files[0];
    console.log('doupload',entry,data)
    fetch('uploads/' + encodeURIComponent(entry.name), {method:'PUT',body:data});
    alert('your file has been uploaded');
    location.reload();
};

如果您喜欢 StackSnippets...

PUT方法与POST方法略有不同在这种情况下,在用于 chrome 的 Web 服务器中,POST未实现方法。

使用 chrome 网络服务器进行测试 - https://chrome.google.com/webstore/detail/web-server-for-chrome/ofhbbkphhbklhfoeikjpcbhemlocgigb?hl=en

注意 - 使用 chrome 的网络服务器时,您需要进入高级选项并选中“启用文件上传”选项。如果你不这样做,你会得到一个不允许的错误。