【问题标题】:Getting '400 Bad Request' when using multipart/form-data as Content-Type in XHR在 XHR 中使用 multipart/form-data 作为 Content-Type 时收到“400 Bad Request”
【发布时间】:2011-06-14 00:13:25
【问题描述】:

我有一个发送一些数据的 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”标头,但这显然对我没有帮助。

我猜有一个可以设置的有效 Content-Type 标头列表,“multipart/form-data”不在其中,但我找不到解决我的困境的方法。

实际发送的数据示例:

内容类型:multipart/form-data;边界=l3iPy71otz

--l3iPy71otz
内容处置:表单数据;名称="titluPublic"

变体_1
--l3iPy71otz
内容处置:表单数据;名称="nr_versiune"


--l3iPy71otz--

谢谢!

【问题讨论】:

标签: javascript ajax header http-headers xmlhttprequest


【解决方案1】:

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

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

更多信息请见RFC 2045

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

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

更新:我发现的另一个问题on the net 出现在将charset 添加到请求标头中的Content-type 中,而不是在正文中的消息边界中(这也是对您的测试用例来说是正确的)。这似乎不是一个可行的解决方案,但也许会有所帮助。

在您的情况下,将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 位于每个 边界,甚至是最后一个边界。为了防止混淆,我决定在请求标头 before 边界参数中显式设置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);

【讨论】:

  • 实际代码为here。只需按下第一个操作按钮(不是删除按钮 :)),您就会看到我正在处理的页面。如果您提交表单(页面底部),您将收到实际的 400 错误。 javascript 文件是here - 我在生成错误请求错误的部分附近发表了评论。非常感谢!!!!!!
  • @Sorin:你为什么将Content-length明确设置为8000? AFAIK,你真的不应该那样做。
  • @Marcel Korpel:我只是在尝试不同的解决方案。我把它拿出来了。
  • @Marcel:我添加了字符集,但它仍然无法正常工作。我对 javascript 和 ajax 还很陌生,所以你可以想象这一定是多么令人沮丧..
  • @Marcel: 就[23/Jan/2011:01:13:53 +0200] "POST /florin2/request.php?action=produsUpdate&id=24556 HTTP/1.1" 404 - "http://clienti.bsorin.ro/florin2/cautare" "Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.6; en-US; rv:1.9.2.13) Gecko/20101203 Firefox/3.6.13"
猜你喜欢
  • 2015-05-30
  • 2018-03-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-12-16
  • 2022-07-23
  • 1970-01-01
  • 2020-01-15
相关资源
最近更新 更多