2018-12-23 15:00:54 253次浏览 3条回答 0 悬赏 100 金钱

这大概是跨越问题导致的 浏览器在发送 post 请求前会发一个 options 请求,如果失败就不会执行 post 请求。 我也设置了一些 header,但好像没什么用

$behaviors['corsFilter'] = [
    'class' => Cors::className(),
    'cors' => [
        // restrict access to
        'Origin' => ['127.0.0.1:80', 'http://127.0.0.1:3002', 'https://wxcwap.meikeyun.com'],
        // Allow only POST and PUT methods
        'Access-Control-Request-Method' => '*',
        // Allow only headers 'X-Wsse'
        // 'Access-Control-Request-Headers' => ['X-Wsse'],
        // Allow OPTIONS caching
        'Access-Control-Allow-Credentials' => null,
        // Allow the X-Pagination-Current-Page header to be exposed to the browser.
        // 'Access-Control-Max-Age' => 3600,
        // 'Access-Control-Expose-Headers' => ['X-Pagination-Current-Page'],
        'Access-Control-Expose-Headers' => [
            'Authorization',
            'X-Pagination-Current-Page',
            'X-Pagination-Page-Count',
            'X-Pagination-Per-Page',
            'X-Pagination-Total-Count'
        ],
    ],
];
$behaviors['authenticator'] = [
    'class' => CompositeAuth::className(),
    'optional' => $this->optional(),
    'authMethods' => [
        HttpBasicAuth::className(),
        HttpBearerAuth::className(),
        QueryParamAuth::className(),
    ],
];
亿速云

最佳答案

  • 刘师傅 发布于 2018-12-23 19:20 举报

    这个简单,其实如果你的应用不是针对全世界广大群众的,那么就不用那么限制Origin。

    header('Access-Control-Allow-Origin:*');
    

    PHP这边只要把客户端需要的关键几个header准备好就行,无论是不是发送options请求都
    把这些header发送给客户端浏览器也无所谓,你可以把发送header的部分写到构造函数里。

    接下来就要判断是不是OPTIONS的请求,如果是,那就一个exit()搞定。你说呢?

    if (Yii::$app->getRequest()->getMethod() === 'OPTIONS') {
      exit;
    }
    

    上面这个,你不想执行action的话,那可以写到beforeAction里,你觉得呢?
    这样在options这一请求,浏览器永远会收到可以放行的信号;那么你只要做好token验证就行了。
    你觉得咋样?

    2 条回复
    回复于 2018-12-24 22:59 回复

    谢谢你的解答,我看了源码之后发现是配置项出错了,'Access-Control-Request-Method' => ['*'],这样就可以得到options返回200,'Access-Control-Request-Headers' => ['Authorization']这样就可以进行认证,但是我现在想知道另外一个优化方案,就是我的所有请求必须在verbs里配置支持OPTIONS才行,我觉得这样是不合理的,请问有什么好的办法吗

    `protected function verbs()

    {
        $verbs = parent::verbs();
        $verbs['register'] = ['POST'];
        $verbs['login-by-id'] = ['POST'];
        return $verbs;
    }`
    
    回复于 2018-12-24 23:40 回复

    这个问题我最终得到了几乎完美的解决方案,behaviors验证的时候有个顺序,只需要把corsFilter的顺序提前到verbFilter就可以在验证是否允许OPTIONS类型请求之前就返回200的成功码。

    PS:问这个问题还遇到一点波折,在一个YII群里问问题,结果有个自以为是的大佬一个劲的鄙视我,然后BB一大堆restful的知识,说我这api不是restful的,这这那那的。不管怎样吧,没帮上忙,还T我出群里,如果这个答案帮到你,希望大家能做一个谦虚一点的人,引以为耻。

您需要登录后才可以回答。登录 | 立即注册
数字派
经理

数字派 北京

注册时间:2016-04-19
最后登录:2天前
在线时长:47小时42分
  • 粉丝10
  • 金钱1010
  • 威望10
  • 积分1580

热门问题