我正在使用java-server(没有JSP,只有com.sun.net.httpserver.HttpServer;
)和web前端作为客户端构建客户端 - 服务器应用程序。我使用WebSockets进行通信,并希望使用XMLHttpRequests和FormData上传文件(我跟着这篇文章Track ajax post progress for fileupload using jquery ajax and FormData)。我希望使用xhr.upload.onprogress
跟踪上传进度,但只要添加一个监听器,例如
xhr.upload.onprogress = function(e) {...};
或
xhr.upload.addEventListener("progress", function (e) {...}, false);
我收到像这样的服务器端错误:
org.apache.commons.fileupload.FileUploadBase$InvalidContentTypeException: the request doesn't contain a multipart/form-data or multipart/mixed stream, content type header is null
at org.apache.commons.fileupload.FileUploadBase$FileItemIteratorImpl.<init>(FileUploadBase.java:948)
at org.apache.commons.fileupload.FileUploadBase.getItemIterator(FileUploadBase.java:310)
at org.apache.commons.fileupload.FileUploadBase.parseRequest(FileUploadBase.java:334)
at com.awaker.server.HttpUploadServer.handle(HttpUploadServer.java:42)
at com.sun.net.httpserver.Filter$Chain.doFilter(Filter.java:79)
at sun.net.httpserver.AuthFilter.doFilter(AuthFilter.java:83)
at com.sun.net.httpserver.Filter$Chain.doFilter(Filter.java:82)
at sun.net.httpserver.ServerImpl$Exchange$LinkHandler.handle(ServerImpl.java:675)
at com.sun.net.httpserver.Filter$Chain.doFilter(Filter.java:79)
at sun.net.httpserver.ServerImpl$Exchange.run(ServerImpl.java:647)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
我使用Apache Commons FileUpload框架来处理上传请求。
这发生在Firefox和Opera(我测试的唯一浏览器)中,虽然Firebug /开发者控制台中列出了正确的Content-Type标头,但服务器不会收到此标头(Content-Length标头也是如此)。
如果我使用jQuery ajax
并不重要$.ajax({
url: "http://host...",
type: "POST",
data: ajaxData,
cache: false,
contentType: false,
processData: false,
xhr: function () {
var xhr = jQuery.ajaxSettings.xhr();
if (xhr.upload) {
xhr.upload.addEventListener("progress", function (e) {
console.log("hello");
}, false);
}
return xhr;
}
});
或vanilla js
var xhr = new XMLHttpRequest();
xhr.upload.onprogress = uploader.uploadProgress;
xhr.open("POST", "http://host...");
xhr.send(formData);
我总是得到同样的错误。 一旦我删除onprogress-handler,一切正常。 我已经尝试了这个FormData boundary missing from content-type in POST request header,但这对我也不起作用。
有人知道如何解决这个问题吗? 谢谢!
编辑: ajaxData是从drop事件生成的:
var droppedFiles = e.originalEvent.dataTransfer.files;
var ajaxData = new FormData();
ajaxData.append("file", droppedFiles[0]);
contentType:false选项允许jQuery / XHR自动添加带有必要边界的Content-Type标头。此选项是必需的,没有它就无法使用。
EDIT2: 这很好用
$.ajax({
url: "http://host...",
type: "POST",
data: ajaxData,
cache: false,
contentType: false,
processData: false,
xhr: function () {
var xhr = jQuery.ajaxSettings.xhr();
return xhr;
}
});
似乎只添加进度监听器才有所作为。
EDIT3: 以下是抛出错误的服务器端代码:
@Override
public void handle(HttpExchange httpExchange) throws IOException {
DiskFileItemFactory diskFileItemFactory = new DiskFileItemFactory();
ServletFileUpload fileUpload = new ServletFileUpload(diskFileItemFactory);
try {
List<FileItem> result = fileUpload.parseRequest(new HttpHandlerRequestContext(httpExchange));
(...)
} catch (FileUploadException e) {
e.printStackTrace();
}
}
我按照这个回答https://stackoverflow.com/a/33827895/6655315。 HttpHandlerRequestContext与链接帖子中显示的完全相同。
Edit4: 只需添加一个像这样的空上传进度处理程序
xhr.upload.onprogress = function(e) {};
收到的标题正在从此更改
Accept-encoding: gzip, deflate
Origin: http://localhost:63343
Accept: */*
Referer: http://localhost...
Connection: keep-alive
Host: localhost:4734
Dnt: 1
User-agent: Mozilla/5.0 (Windows NT 6.3; WOW64; rv:47.0) Gecko/20100101 Firefox/47.0
Accept-language: de,en-US;q=0.7,en;q=0.3
Content-type: multipart/form-data; boundary=---------------------------63422017421660
Content-length: 333700
到此:
Accept-encoding: gzip, deflate
Access-control-request-method: POST
Origin: http://localhost:63343
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Connection: keep-alive
Host: localhost:4734
Dnt: 1
User-agent: Mozilla/5.0 (Windows NT 6.3; WOW64; rv:47.0) Gecko/20100101 Firefox/47.0
Accept-language: de,en-US;q=0.7,en;q=0.3