ChatGPT解决这个技术问题 Extra ChatGPT

JavaScript:上传文件

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

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

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

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

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

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

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

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

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

JavaScript 不处理上传,因为它是服务器端的。服务器端脚本将接收文件,然后移动它。对于从临时文件夹到所需文件夹的 php。
投票重新开放,因为问题是关于 POJS(普通的旧 javascript)而不是 jQuery。

B
Bhargav Rao

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

异步函数 SavePhoto(inp) { let user = { name:'john', age:34 };让 formData = new FormData();让照片 = inp.files[0]; formData.append("照片", 照片); formData.append("用户", JSON.stringify(user)); const ctrl = new AbortController() // 超时 setTimeout(() => ctrl.abort(), 5000);尝试 { let r = await fetch('/upload/image', {method: "POST", body: formData, signal: ctrl.signal}); console.log('HTTP响应码:',r.status); } catch(e) { console.log('休斯顿我们有问题...:', e); } }

在选择文件之前打开 chrome 控制台 > 网络选项卡以查看请求详细信息。

因为在这个例子中我们向 https://stacksnippets.net/upload/image 发送请求,所以响应代码将是 404 ofcourse...

(在堆栈溢出片段存在错误处理问题,但是在 jsfiddle 版本 中,404 错误 4xx/5xx 是 不抛出但我们可以读取包含代码的响应状态)

老派方法 - 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 };让 xhr = new XMLHttpRequest();让 formData = new FormData();让照片 = e.files[0]; formData.append("用户", JSON.stringify(user)); formData.append("照片", 照片); xhr.onreadystatechange = state => { console.log(xhr.status); } // 错误处理 xhr.timeout = 5000; xhr.open("POST", '/upload/image'); xhr.send(formData); }

选择文件并打开 chrome 控制台 > 网络选项卡以查看请求详细信息。

因为在本例中,我们将请求发送到 https://stacksnippets.net/upload/image,所以响应代码将是 404 ofcourse...

(堆栈溢出片段,在错误处理方面存在一些问题 - xhr.status 为零(而不是 404),这类似于我们从 本地光盘 - 所以我还提供了 js fiddle 版本,它显示了正确的 http 错误代码 这里 )

概括

在服务器端,您可以读取原始文件名(和其他信息),这些文件名自动包含在文件名 formData 参数中的浏览器请求中。

您不需要将请求标头 Content-Type 设置为 multipart/form-data - 这将由浏览器自动设置(包括强制边界参数)。

而不是 /upload/image 你可以使用像 http://.../upload/image 这样的完整地址(当然这两个地址都是任意的,并且取决于服务器 - 与参数方法相同的情况 - 通常在服务器上使用“POST”用于文件上传,但有时可以使用“PUT”或其他)。

如果您想在单个请求中发送多个文件,请使用多个属性:,并以类似的方式将所有选择的文件附加到 formData(例如 photo2=...files[2];... formData.append("photo2", photo2);)

您可以包含附加数据(json)以请求例如 let user = {name:'john', age:34} 以这种方式: formData.append("user", JSON.stringify(user));

您可以设置超时:使用 AbortController 获取,旧方法通过 xhr.timeout=milisec

此解决方案应适用于所有主要浏览器。


formData === 表单提交enctype="multipart/form-data"
我收到错误 net::ERR_ABORTED 405 (Method Not Allowed)
@HidaytRahman 当服务器没有为您的网址实现 POST 方法时,通常会出现此错误
奇怪-根据您的标题,我认为我们不再需要服务器:D
我得到POST http://localhost:8000/upload/image 404 (Not Found)。在我的 React Node 测试项目的 /src 和 /public 下创建 /upload/image。
C
Community

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

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

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

使用jsp和javascript进行异步文件上传(AJAX文件上传)

jQuery Ajax 文件上传

Ajax 使用文件上传


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

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

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

<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...

函数 doupload() { 让数据 = document.getElementById("file").files[0];让 entry = document.getElementById("file").files[0]; console.log('doupload',entry,data) fetch('uploads/' + encodeURIComponent(entry.name), {method:'PUT',body:data}); alert('您的文件已上传'); };

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

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

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