Ich baue eine Client-Server-Anwendung mit einem Java-Server (keine JSP, nur com.sun.net.httpserver.HttpServer;
) und Web-Frontend als Client. Ich benutze WebSockets für die Kommunikation und möchte Dateien mit XMLHttpRequests und FormData hochladen (ich folgte diesem Beitrag Track ajax post progress for fileupload using jquery ajax and FormData). Ich möchte mit xhr.upload.onprogress
den Upload-Fortschritt verfolgen, aber sobald ich ein Zuhörer wieFormData File Upload mit Progress Listener Content-Type-Header fehlt
xhr.upload.onprogress = function(e) {...};
oder
xhr.upload.addEventListener("progress", function (e) {...}, false);
ich so erhalten einen server Fehler hinzu:
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)
Ich verwende das Apache Commons FileUpload Framework für die Verarbeitung von Upload-Anfragen.
Dies geschieht in Firefox und Opera (die einzigen Browser, die ich getestet habe), und während die richtigen Content-Type-Header in Firebug/Developer Console aufgeführt sind, erhält der Server diesen Header nicht (dasselbe gilt für Content-Length-Header) .
Es spielt keine Rolle, ob ich Ajax
jQuery$.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;
}
});
oder Vanille js
var xhr = new XMLHttpRequest();
xhr.upload.onprogress = uploader.uploadProgress;
xhr.open("POST", "http://host...");
xhr.send(formData);
ich die gleichen Fehler immer. Sobald ich den onprogress-Handler entferne, funktioniert alles gut. Ich habe das schon probiert FormData boundary missing from content-type in POST request header, aber das funktioniert auch nicht für mich.
Weiß jemand, wie man das löst? Vielen Dank!
Edit: Die ajaxData werden aus einem Drop-Ereignis generiert:
var droppedFiles = e.originalEvent.dataTransfer.files;
var ajaxData = new FormData();
ajaxData.append("file", droppedFiles[0]);
Die content: false Option können jQuery/XHR automatisch den Content-Type-Header mit der notwendigen Grenze hinzuzufügen. Diese Option ist erforderlich, ohne sie geht es nicht.
Edit2: Dies funktioniert
$.ajax({
url: "http://host...",
type: "POST",
data: ajaxData,
cache: false,
contentType: false,
processData: false,
xhr: function() {
var xhr = jQuery.ajaxSettings.xhr();
return xhr;
}
});
Es scheint nur, dass der Fortschritt Zuhörer Zugabe einen Unterschied macht.
Edit3: Hier ist die serverseitige Code, der den Fehler auslöst:
@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();
}
}
i https://stackoverflow.com/a/33827895/6655315 diese Antwort folgte. Der HttpHandlerRequestContext entspricht genau dem im verknüpften Post.
Edit4: nur durch einen leeren Upload-Fortschritt-Handler wie diese Zugabe
xhr.upload.onprogress = function(e) {};
die empfangenen Header werden von diesem auf diese
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
Wechsel:
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
entfernen 'content lesen würde empfehlen: false,' jq sollte den Rest – dandavis
Dank handhaben, aber das funktioniert nicht, da ich bin mit Formdata, für die der Content-Type-Header die Grenze benötigt. Das Entfernen führt zu dem obigen Fehler. – teyzer
Haben Sie jemals herausgefunden, warum der Onprogress Event-Handler die Kopfzeile geändert hat und was der Fix dafür ist? – shreddish