【问题标题】:Symfony 2 - Allow OPTIONS requestsSymfony 2 - 允许 OPTIONS 请求
【发布时间】:2018-02-06 15:28:13
【问题描述】:

我有一个 symfony 2 后端,我已经将它安装在服务器上。我的前端是一个离子 PWA,所以它在浏览器中运行,它也安装在该服务器上,但带有另一个子域。当我从网络应用程序向后端发送请求时,我收到此错误:

选项https://api.example.com/api/login.json

XMLHttpRequest 无法加载 https://api.example.com/api/login.json。回复 预检有无效的 HTTP 状态代码 405

这是我的登录操作代码:

/**
 * Login via username and password or via API key
 *
 * @Doc\ApiDoc(
 *  section="Security",
 *  description="Login",
 *  views={"default", "security"}
 * )
 *
 * @param ParamFetcher $params
 *
 * @Rest\RequestParam(name="username", nullable=true, description="Username")
 * @Rest\RequestParam(name="password", nullable=true, description="Password")
 * @Rest\RequestParam(name="apikey", nullable=true, description="API key (alternative to username + password)")
 *
 * @Rest\Post("/login", name="api_security_login", options={"method_prefix" = false})
 *
 * @return Response
 */
public function loginAction(ParamFetcher $params)
{
    //...do some stuff here...//

    $data = array(
        'user'   => $userValue,
        'apikey' => $user->getApiKey(),
    );

    $groups = array('default', 'private');

    return $this->createAPIResponse(self::STATUS_OK, $data, $groups);
}

这是响应的标题:

Access-Control-Allow-Methods:GET,POST,OPTIONS,DELETE,PUT
Access-Control-Allow-Origin:*
Allow:POST
Cache-Control:no-cache
Connection:Keep-Alive
Content-Length:54
Content-Type:application/json
Date:Tue, 29 Aug 2017 08:33:26 GMT
Keep-Alive:timeout=5, max=100
Server:Apache

这是 prod.log 文件中的错误消息:

request.ERROR: 未捕获的 PHP 异常 Symfony\Component\HttpKernel\Exception\MethodNotAllowedHttpException: “未找到“OPTIONS /api/login.json”的路由:不允许的方法 (允许:POST)”在 /var/www/example.com/api/htdocs/symfony/vendor/symfony/symfony/src/Symfony/Component/HttpKernel/EventListener/RouterListener.php 第 163 行 {“异常”:“[对象] (Symfony\Component\HttpKernel\Exception\MethodNotAllowedHttpException(代码: 0): 没有为 \"OPTIONS /api/login.json\" 找到路由: 方法不允许 (允许:POST)在 /var/www/example.com/api/htdocs/symfony/vendor/symfony/symfony/src/Symfony/Component/HttpKernel/EventListener/RouterListener.php:163, Symfony\Component\Routing\Exception\MethodNotAllowedException(代码: 0): 在 /var/www/example.com/api/htdocs/symfony/app/cache/prod/appProdUrlMatcher.php:855)"} []

因此,由于“允许”标头仅允许“POST”,因此似乎不允许发送因为 CORS 而发送的 OPTIONS 请求。那么解决所有路线的最佳方法是什么?

【问题讨论】:

    标签: php api symfony request options


    【解决方案1】:

    没有接受选项http方法的路由。

    No route found for "OPTIONS /api/login.json"
    

    你需要先定义它:

    /**
     * @Rest\Route(
     *   "/login", 
     *   name="api_security_login",
     *   methods = { 
     *     Request::METHOD_POST,
     *     Request::METHOD_OPTIONS,
     *   }
     * )
     */
    

    之后清除缓存并验证路由是否处于活动状态,即使用:

    bin/console debug:router | grep -i api_security_login
    

    【讨论】:

    • 它不适合我。即使应该,我也必须编辑每条路线......但似乎没有简单的方法。
    • 你问为什么你的路由不工作,答案显然是“因为它不存在”,我们可以从 symfony 抛出的异常中看出。不涉及 CORS 问题。应用我建议的更改后,bin/console debug:router | grep -i api_security_login 的输出是什么?
    • 我建议我们首先找出对单个 OPTIONS 请求不起作用的原因。然后我们允许所有控制器操作/路由的选项方法。有一种简单的方法,但如果您只是说它对我不起作用并且您没有提供有关您的应用程序行为、异常消息或命令输出的任何信息,那么我无法为您提供帮助应用了更改。
    • 但是 OPTIONS 请求是因为 CORS 而发送的,我不是自己发送的。而且我不明白为什么没有简单的方法来接受每条路线的请求并用应该回答的任何内容来响应它。 ...我刚刚将您的代码添加到注释块中。还是我必须将其替换为 Post 注释?因为现在我有带有“POST|OPTIONS”的“loginapi_security_login”和带有“POST”的“api_security_login”。
    • 您需要删除 @Rest\Post 注释并将其替换为 @Rest\Route .... 或添加 @Rest\Options 但您需要为路线使用不同的名称,否则POST 路由将被覆盖。
    【解决方案2】:

    对于POST 方法,您的操作只有一条路线:

    @Rest\Post("/login", name="api_security_login", options={"method_prefix" = false})

    如果您想回答OPTIONS 请求,您必须使用@Rest\Options 注释定义选项路由。

    您可以在同一个操作上使用多个注释并测试操作内的方法(通常是GETPOST 用于表单操作),或者定义两个具有相同路径但方法不同的不同操作.

    http://symfony.com/doc/master/bundles/FOSRestBundle/7-manual-route-definition.html

    【讨论】:

    • 已经在帖子下面用@Rest\Options("/login", name="api_security_login_options", options={"method_prefix" = false})试过了,还是一样的问题
    猜你喜欢
    • 2019-05-15
    • 2014-09-27
    • 2012-11-24
    • 2015-10-06
    • 2023-04-02
    • 2017-07-04
    • 2016-07-27
    • 2017-03-15
    • 2015-02-09
    相关资源
    最近更新 更多