【发布时间】:2012-03-12 20:19:14
【问题描述】:
我可以通过XMLHttpRequest 将文件作为多部分发送到 servlet 吗?
我正在制作一个表单并将其作为多部分提交,但不知何故我没有收到成功上传它的响应。我不想刷新页面,所以它必须由 Ajax 进行。
【问题讨论】:
标签: javascript ajax servlets file-upload multipart
我可以通过XMLHttpRequest 将文件作为多部分发送到 servlet 吗?
我正在制作一个表单并将其作为多部分提交,但不知何故我没有收到成功上传它的响应。我不想刷新页面,所以它必须由 Ajax 进行。
【问题讨论】:
标签: javascript ajax servlets file-upload multipart
这只能通过 XHR FormData API(以前称为“XHR2”或“XHR Level 2”的一部分,目前称为“XHR 高级功能”)实现。
鉴于此 HTML,
<input type="file" id="myFileField" name="myFile" />
你可以上传如下:
var formData = new FormData();
formData.append("myFile", document.getElementById("myFileField").files[0]);
var xhr = new XMLHttpRequest();
xhr.open("POST", "myServletUrl");
xhr.send(formData);
XHR 将注意正确的标头和请求正文编码,并且在此示例中,文件将在服务器端以 form-data 部分的名称myFile 的形式提供。
您需要记住,旧版浏览器不支持FormData API。在caniuse.com,您可以看到它目前已在 Chrome 7+、Firefox 3.5+、Safari 5+、Internet Explorer 10+ 和Opera 12+ 中实现。
如果您使用的是 jQuery,那么您可能会想使用它的 $.val() 函数,如下所示:
formData.append("myFile", $("#myFileField").val());
但这是不正确的,因为它不会返回整个 File 对象,而只是返回 String 的文件名,因为它不包含文件内容,所以完全没用。
如果您出于某种原因不想使用 document.getElementById(),请改用以下方法之一:
formData.append("myFile", $("#myFileField").prop("files")[0]);
formData.append("myFile", $("#myFileField")[0].files[0]);
另一种方法是使用jQuery Form plugin。您的整个表单,如果在没有任何 JavaScript 代码行的情况下编写并正常运行,那么将立即使用以下行进行 ajaxified:
$("#formId").ajaxForm(function(response) {
// Handle Ajax response here.
});
它还通过隐藏的 iframe 技巧支持文件上传。另请参阅this jQuery Form documentation 以获得深入的解释。您可能只需要更改 servlet 代码即可拦截正常(同步)和 Ajax(异步)请求。另请参阅此答案以获取具体示例:Simple calculator with JSP/Servlet and Ajax
无论哪种方式,上传的文件都应该在@MultipartConfig servlet 的doPost() 方法中可用,如下所示:
Part myFile = request.getPart("myFile");
或者,如果您仍在使用 Servlet 2.5 或更早版本,请按常规方式使用 Apache Commons FileUpload。另请参阅此答案以获取具体示例:How can I upload files to a server using JSP/Servlet?
【讨论】:
Content-type', 'multipart/form-data' 时,我的请求都会失败,但如果未指定标头则可以。但为什么呢?
无法使用 XMLHttpRequest 发送multipart/form-data(尽管在现代浏览器中可以使用XHR2。请参阅BalusC's answer)。
实现您想要的一个常见方法是使用常规form,但改为使用iframe。这样,上传时只会刷新iframe。
【讨论】: