在XHR中使用multipart / form-data作为Content-Type时获得'400 Bad Request'

时间:2011-01-23 12:10:32

标签: javascript ajax header http-headers xmlhttprequest

我有一个发送一些数据的AJAX请求。数据尊重multipart / form-data specification

我面临的问题是浏览器将Content-Type标头设置为text / plain,它应该是multipart / form-data。

我尝试过这样做:request.setRequestHeader("Content-Type", "multipart/form-data");但这会产生400 Bad Request错误。

如果我request.setRequestHeader("Content-Typexxxx", "multipart/form-data");没有错误,则设置“Content-Typexxxx”标题但显然对我没有帮助。

我想有一个可以设置的有效内容类型标题列表,而“multipart / form-data”不在其中,但我无法找到解决问题的方法。

实际发送的数据样本:

Content-Type: multipart/form-data; boundary=l3iPy71otz

--l3iPy71otz
Content-Disposition: form-data; name="titluPublic"

Variation_1
--l3iPy71otz
Content-Disposition: form-data; name="nr_versiune"


--l3iPy71otz--

谢谢!

1 个答案:

答案 0 :(得分:4)

您没有在请求标头中设置boundary,如:

request.setRequestHeader("Content-Type", "multipart/form-data; boundary=l3iPy71otz");

有关详细信息,请参阅RFC 2045

  

5内容类型标题字段
[...]
  参数是媒体的修饰符   子类型,因此不这样做   从根本上影响了性质   内容。这套有意义的   参数取决于媒体类型   和子类型。大多数参数是   与单个特定相关联   亚型。但是,给定的   顶级媒体类型可以定义   适用于的参数   该类型的任何子类型。参数   可能需要他们的定义   内容类型或子类型或它们可能是   可选的。 MIME实现必须   忽略任何名字的参数   不承认。

     

例如,“charset”   参数适用于任何子类型   “文字”,而“边界”   任何子类型都需要参数   “多部分”媒体类型。

更新:当charset添加到请求标头中的Content-type但未添加到消息边界时,我发现on the net的另一个问题身体(对于您的测试用例也是如此)。它似乎不是一个可能的解决方案,但也许它会有所帮助。

在您的情况下,明确向请求标头和消息边界添加charset

data.params += "--" + data.uniqid + "; charset=UTF-8" + data.crlf;
…
request.setRequestHeader("Content-Type", "multipart/form-data; boundary=" + data.uniqid + "; charset=UTF-8");

更新2:在本地尝试此操作后,我注意到前导边界未被识别,但被解释为最后一个参数内容(在我更宽容的服务器上)。也许这导致Apache抛出400 Bad Request错误。

经过一些试验和错误后,我注意到这是因为服务器期望charset位于每个边界,即使是最后一个。{为了避免混淆,我决定在边界参数之前在请求标头中显式设置charset,以便边界将是Content-type请求标头中的最后一个参数。在此之后,一切似乎都运转正常。

data.params = "Content-Type: multipart/form-data; boundary=" + data.uniqid;
…
data.params += "--" + data.uniqid + data.crlf;
…
data.params += "--" + data.uniqid + "--";
…
request.setRequestHeader("Content-Type", "multipart/form-data; charset=UTF-8; boundary=" + data.uniqid);