Symfony2路由无法识别http POST


Symfony2 routing not recognizing http POST?

我最近开始使用Symfony Routing 组件。

我的路由 yaml 如下所示:

custom:
  path: /custom
  defaults: {controller: custom, action: refresh}
  methods: [POST]
  schemes: [https]
default:
    path: /{controller}/{action}
    defaults: {controller : index, action: index}

但是,url https://my.domain.com/custom"被解析为默认路由,即使它遵循yaml文件中的自定义路由。根据我的jQuery .ajax设置和Chrome控制台,请求方法是POST:

XHR finished loading: POST "https://my.domain.com/custom".

或根据 Chrome 网络 -> 标头:

Request URL:https://my.domain.com/custom
Request Method:POST

如果我将请求方法更改为 get,保持 yaml 配置不变,它也不会起作用,这当然是意料之中的。如果我将自定义路由的 yaml 配置更改为接受 GET 而不是 POST,并发送 GET 请求,它确实可以正常工作,再次按预期。但是,如果我更改自定义路由的 yaml 配置以接受 GET 并发送 POST 请求,它可以工作,即自定义规则匹配!从某种意义上说,浏览器的 POST 请求似乎在服务器端被解释为 GET。

在这种情况下,这是某种奇怪的Chrome错误,我尝试过Firefox,结果相同。

然后我尝试打印 $_SERVER['REQUEST_METHOD'],结果符合预期,如果请求是 POST,则为 POST,如果请求是 GET,则为 GET。所以在我看来,这是Symfony的错,也许我配置错误了。

这是我相关的PHP代码:

$args       = isset($_REQUEST['args']) ? $_REQUEST['args'] : '';
$request    = Request::createFromGlobals();
$locator    = new FileLocator(HOME_PATH . 'config');
$loader     = new YamlFileLoader($locator);
$routes     = $loader->load('routes.yml');
$context    = new RequestContext($_SERVER['REQUEST_URI']);
$context->setScheme($request->getScheme());
$context->setHost($_SERVER['SERVER_NAME']);
$matcher    = new UrlMatcher($routes, $context);
try
{
    $match          = $matcher->match('/' . rtrim($args, '/'));
....
}
....

有一种强烈的感觉,我只是在这里对请求和上下文做了一些根本错误的事情,但这就是我设法让它们工作的方式,到目前为止它曾经运行良好,至少在 GET 路由上是这样。提前感谢您的帮助!

很抱歉迟到了将近两年,但我自己解决了这个问题。

您必须使用 Request 对象为 RequestContext 对象设定种子:

$request = Request::createFromGlobals();
$context = new RequestContext($_SERVER['REQUEST_URI']);
$context->fromRequest($request);
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

解释:

遇到了同样的问题(当我发现这个未回答的问题时,我感到很生气),并深入研究了源代码以弄清楚为什么它声称"GET"是每个请求的方法。

我的错误是认为 UrlMatcher 正在使用 Request 对象(转储时显示"POST"),但它没有;它使用 RequestContext 对象。

你可以在symfony/routeting/Matcher/UrlMatcher的第153行看到这一点.php

151 if ($requiredMethods = $route->getMethods()) {
152     // HEAD and GET are equivalent as per RFC
153     if ('HEAD' === $method = $this->context->getMethod()) {
                                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^
154         $method = 'GET';
155     }

。当我检查 RequestContext 类时,我发现构造函数默认为 GET:

52     public function __construct($baseUrl = '', $method = 'GET', $host = 'loc....

但我很高兴也发现了fromRequest方法,它很高兴地解释了它如何在文档块中解决我们的问题:

64     /**
65      * Updates the RequestContext information based on a HttpFoundation Request.
          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^
66      *
67      * @param Request $request A Request instance
68      *
69      * @return RequestContext The current instance, implementing a fluent interface
70      */
71     public function fromRequest(Request $request)
72     {
73         $this->setBaseUrl($request->getBaseUrl());
74         $this->setPathInfo($request->getPathInfo());
75         $this->setMethod($request->getMethod());
76         $this->setHost($request->getHost());
77         $this->setScheme($request->getScheme());
78         $this->setHttpPort($request->isSecure() ? $this->httpPort : $request->getPort());
79         $this->setHttpsPort($request->isSecure() ? $request->getPort() : $this->httpsPort);
80         $this->setQueryString($request->server->get('QUERY_STRING', ''));
81
82         return $this;
83     }

干杯!

我的问题是当 URL 以 /(斜杠)结尾时我无法匹配路由