我正在用PHP创建RESTful API,但遇到了问题。 当客户端将数据发布到服务器时,服务器应返回:
Status code 201 CREATED
Header Location with the location of the new object
Content-Type application/xml
<SomeXmlData></SomeXmlData>
虚拟代码,在我的计算机上产生问题:
<?php
header("Location: http://google.no/",true,201);
header("Content-Type: application/xml;charset=iso-8859-1");
echo "<?xml version=\"1.0\" encoding=\"utf-8\" standalone=\"yes\"?>\n";
echo "<Jada></Jada>";
?>
HTTP结果是
HTTP/1.1 201 Created
Content-Type: text/html; charset=UTF-8
Location: http://google.no/
Server: Microsoft-IIS/7.5
X-Powered-By: PHP/5.4.5
X-Powered-By: ASP.NET
Date: Wed, 22 Aug 2012 13:52:57 GMT
Content-Length: 209
<head><title>Document Moved</title></head>
<body><h1>Object Moved</h1>This document may be found <a HREF="http://google.no/">here</a></body><?xml version="1.0" encoding="utf-8" standalone="yes"?>
<Jada></Jada>
由于位置标题,PHP会自动将一些HTML代码和HTML内容类型添加到响应中。
因此,我的api无法与其客户合作。
编辑: IIS 7.5 Windows 7 Proffesional
答案 0 :(得分:4)
我很抱歉收到坏消息,但请看这里:
Prevent IIS from changing response when Location header is present
编辑:从来没有找到答案 - 我最终切换到Apache
似乎IIS已经很长时间陷入了标题:
http://forums.iis.net/t/1158431.aspx
这是IIS FastCGI模块中的一个错误。它将在Windows 7 RTM中修复。我们还在研究为IIS 7提供此修复程序的可能方法。
希望如果错误相关(我希望它们是相关的),如果您现在拥有FastCGI,那么下面的修复可能会有效。否则,切换到PHP非FastCGI模块也可能有效,而且可能比投入Apache更容易。
答案 1 :(得分:4)
解决方案是创建一个IIS模块,在FastCGI完成后将标题“Custom-Location”重写为“Location”。
然后,FastCGI根本不会知道我们正在发送一个Location标头,它不会修改我的响应。
模块:
string Location = context.Response.Headers["Custom-Location"] as string;
if (!string.IsNullOrEmpty(Location))
{
context.Response.Headers.Remove("Custom-Location");
context.Response.AddHeader("Location", Location);
}
PHP:
header("Custom-Location: http://google.no",true,201);
header("Content-Type: application/xml");
echo "<xml></xml>";
(仍然是虚拟代码,而不是极其正确的代码:))
答案 2 :(得分:2)
我在IIS 8.5上遇到了与WP REST API类似的问题。关注html
<head>
<title>Document Moved</title>
</head>
<body>
<h1>Object Moved</h1>
This document may be found
<a HREF="[url-from-location-header]">here</a>
</body>
在每个返回的带有Location
标头和状态201 Created
的json的开头添加了。 Content-Type
已更改为text/html; charset=UTF-8
。
在php.ini中添加cgi.rfc2616_headers = 1
导致:
200 OK
我不会称之为解决方案,这更能解决另一个问题。幸运的是,在我的情况下,这个新问题比原来的要小。
答案 3 :(得分:0)
要规避这种 IIS 行为,您可以使用出站重写规则。以下将查找状态 201,如果是,则删除直到并包括结束正文标记的所有内容行:
<outboundRules>
<rule name="Remove injected 201 content" preCondition="Status 201">
<match filterByTags="None" pattern="^(?:.*[\r\n]*)*.*</body>" />
<action type="Rewrite" value="" />
</rule>
<preConditions>
<preCondition name="Status 201" patternSyntax="Wildcard">
<add input="{RESPONSE_STATUS}" pattern="201" ignoreCase="false" />
</preCondition>
</preConditions>
</outboundRules>