除了PUT或POST,Content-Type头适用于其他HTTP方法吗?

3 投票
2 回答
3011 浏览
提问于 2025-04-16 10:20

我在试用CollectionSpace软件的REST API时,发现如果在GET请求中发送一个Content-Type头,就会出现以下错误:

HTTP Status 415 - Cannot consume content type

我尝试过的两个Python REST客户端库,一个是在GitHub上的restclient,另一个是在Google Code上的python-rest-client,都是在进行GET请求时发送了Content-Type头。

根据我查看的资料,http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html,我了解到客户端应该只在POST和PUT请求中发送Content-Type头。这样理解对吗?

这两个库都发送这个头让我觉得,服务器通常会忽略这个头,而不是返回客户端错误代码。

2 个回答

2

415 无法处理内容类型

这个问题发生在当你的REST资源使用了@Consumes注解,表示它只接受特定的MIME类型时。要解决这个问题,你需要在请求中设置正确的“Accept”头和“Content-Type”头。对于RESTEasy中的MockHttpRequest,可以简单地这样做:

request.accept(MediaType.APPLICATION_JSON);
request.contentType(MediaType.APPLICATION_JSON);

6

虽然在规范中没有明确说明,但我们可以做一些推测。第7.2.1节提到:

任何包含实体主体的HTTP/1.1消息应该包括一个Content-Type头字段,用来定义这个主体的媒体类型。

这点很明显,也很有道理。基于这一点,我们可以看看第9节(方法定义),看看哪些方法提到它们可能在请求主体中包含实体。这里面有三个方法提到过:

OPTIONS

如果OPTIONS请求包含实体主体(通过Content-Length或Transfer-Encoding的存在来指示)...

POST

...用于请求源服务器接受请求中包含的实体...

PUT

...请求将包含的实体存储在提供的Request-URI下。

还有一个方法明确不允许包含实体,那就是TRACE

TRACE请求必须不包含实体。

实际上,你可以用任何方法(除了TRACE)发送一个包含实体的请求主体,并带上Content-Type头。不过,根据规范,我不指望服务器会对这些内容做什么,除非它是上面提到的三种方法之一。


我还想说,你使用的软件如果返回HTTP状态码415,那就是违反了规范。

第4.3节提到:

...如果请求方法没有为实体主体定义语义,那么在处理请求时应该忽略消息主体。

因为规范没有为GET请求的实体主体定义语义,所以服务器应该忽略它。

此外,如果请求中没有提供实体,并且Content-Length为零(假设Transfer-Encoding头没有设置且不是“identity”),那么服务器不应该尝试处理实体,无论请求方法是什么,或者是否存在Content-Type头。这一点可以通过第4.4节中描述的消息长度优先级来支持。

撰写回答