在我的控制器功能中,我需要根据接受的内容类型以及请求的方式返回不同的回复。但由于某些原因,$request->header->get( 'accept' )
或$request->getRequestFormat()
总是返回HTML(或分别为" text / html")虽然浏览器根据Firebug发送了不同的内容,但Wireshark也确认了原始请求真的不一样。
基本上我的代码如下所示:
public function someControllerAction() {
$request = $this->getRequest();
if( $request->isXmlHttpRequest() && $request->getRequestFormat() == 'html' ) {
// (1) Return some HTML fragment that is used to update the DOM at client side
} else if( $request->isXmlHttpRequest() && $request->getRequestFormat() == 'json' ) {
// (2) Return a JSON object
} else if( $request->getRequestFormat() == 'html' ) {
// (3) Return a full HTML page from a TWIG template
}
// In all other cases, return a 406 error
}
由于某种原因,只执行case(1)或case(3),因为请求的格式总是等于HTML。我已经尝试了
die( var_dump( $request->header ) )
看看Symfony认为标题是什么,我注意到标题中的一些其他细微变化与Wireshark所说的相比。例如,所有内容都转换为小写。
目前,我最好的猜测是,在Symfony核心深处的某个地方似乎会发生某种规范化,它也会用默认的" text / html"替换Accept-Header-Field。有趣的是,X-Requested-With-Field没有标准化,但幸存下来。
我需要更改请求对象返回实际(真实)标题字段吗?
更新:
的结果die( var_dump( getallheaders() ) );
也显示错误的标题。 Symfony是否操作本机PHP变量,或者这是否表明Apache在将其传递给PHP处理程序之前会使用accept标头?
答案 0 :(得分:1)
我终于找到了问题所在。首先,正如在另一个答案中已经提到的那样,$request->getRequestFormat()
是另一回事。 (它很难连接到占位符_format
。)但它不是$request-getContentType()
,也不是评论中讨论的。 HTTP-Accept-Header既可以通过$request->headers->get('accept')
获得,也可以通过$request-> getAcceptableContentTypes()
以更易于使用的方式获得。但这只是解决方案的一部分,因为$request->getAcceptableContentTypes()
仍然会返回一个错误值的数组。
最终解决方案是$request
绝不能通过getRequest()
BUT获取作为控制器方法的第一个参数。正如我在Upgrade Guide to Symfony 3中找到的那样
{2.4}已弃用getRequest()
。似乎getRequest()
返回的是与通过参数注入的对象不同的对象,并且在某些条件下,第一种方法不能可靠地保持Accept-Header不变。也许,人们可以称之为一个错误,但如果getRequest()
被弃用,我也不会打扰。 (顺便说一句:为什么甚至官方的Symfony文档“The Book”和“The Cookbook”都提供了使用弃用方法的示例?!)。
无论如何,完全可行的解决方案是
use Symfony\Component\HttpFoundation\Request;
public function someControllerAction( Request $request ) {
if( $request->isXmlHttpRequest() && in_array( 'text/html', $request->getAcceptableContentTypes() ) ) {
// (1) Return some HTML fragment that is used to update the DOM at client side
} else if( $request->isXmlHttpRequest() && in_array( 'application/json', $request->getAcceptableContentTypes() ) ) {
// (2) Return a JSON object
} else if( in_array( 'text/html', $request->getAcceptableContentTypes() ) ) {
// (3) Return a full HTML page from a TWIG template
}
// In all other cases, return a 406 error
}
答案 1 :(得分:0)
请注意$request->getRequestFormat()
不进行实际的格式检查。它仅依赖于_format
请求参数(see the doc)。您应该使用$request->getContentType()
代替。