Content type for file part of the multipart/form-d

2019-05-16 23:46发布

问题:

I'm trying to send multipart/form-data with following JavaScript and jQuery:

var formData = new FormData();

formData.append("projectName", $("#projectNameInput").val());

var file = $("#fileInput")[0].files[0];
formData.append("content", file);

var xhr = new XMLHttpRequest();
xhr.open('POST', '/project', true);
xhr.onload = function(ev) {
  // Handling logic omitted
};
xhr.send(formData);

However, some client browsers (Firefox and Chrome) receive 400 Bad Request from the server. While examining the headers and request payload I discovered that some browsers set explicit content type for the file as follows:

------WebKitFormBoundaryEuDIpEU2Ci8VNwNJ 
Content-Disposition: form-data; name="content"; filename="testfile.ext" 
Content-Type: EXT Project Data (64bit)

------WebKitFormBoundaryEuDIpEU2Ci8VNwNJ

In a working request the Content-Type should be as follows: Content-Type: application/octet-stream, which the server can handle properly.

I suspect this has something to do with browser's configuration or file associations. Is there a way to explicitly set the content type for the file part of the request?

The problem occurs with some users using Firefox and Chrome. However, some users are able to upload succesfully using Chrome and Firefox. IE is not supported by our application.

回答1:

Ok, we managed to figure out this issue. It turned out that the content type registered to the client system was actually malformed on some client machines, that had certain third-party application installed.

We cannot programmatically change the content type browser sets for the part. As Michael-O pointed out, you should always use content-types registered with the IANA. Here's a link to the standard.

In this case it was third-party software that registered illegal content type to client's system. Content type may not contain white spaces, so the content type EXT Project Data is clearly illegal. We fixed the issue by changing the registered content type to a custom content type. So the content type we are now using is application/x-ext-project-data, which is then handled properly on the server side.