关于浏览器预提交的 options 请求,Yii2 该如何快速回应而不执行 action? [ 2.0 版本 ]
这大概是跨越问题导致的
浏览器在发送 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(),
],
];
最佳答案
-
这个简单,其实如果你的应用不是针对全世界广大群众的,那么就不用那么限制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 条回复谢谢你的解答,我看了源码之后发现是配置项出错了,'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; }`
其他 3 个回答
-
`
namespace mycore\libs;
use \Closure;
use Yii;
use yii\base\ActionEvent;
use yii\base\Behavior;
use yii\web\Controller;class CrossOriginBehavior extends Behavior
{public $actions = []; public function events() { return [Controller::EVENT_BEFORE_ACTION => 'beforeAction']; } /** * @param $event * @return bool */ public function beforeAction($event) { $action = $event->action->id; if(in_array($action, $this->actions)){ // 指定允许其他域名访问 //header('Access-Control-Allow-Origin:*'); //header('Access-Control-Allow-Methods:POST,GET,OPTIONS'); //支持的http 动作 //header('Access-Control-Allow-Headers:x-requested-with,content-type'); $response = Yii::$app->getResponse(); $response->getHeaders()->set('Access-Control-Allow-Origin', '*'); $response->getHeaders()->set('Access-Control-Allow-Methods', 'POST,GET,OPTIONS'); $response->getHeaders()->set('Access-Control-Allow-Headers', 'x-requested-with,content-type'); //如果是OPTIONS操作,直接返回页面就可以,不需要返回具体业务信息 if (Yii::$app->request->getMethod() == 'OPTIONS') { $response->data = 'options'; $response->send(); Yii::$app->end(); } return true; } }
}`
在controll中应用
` public function behaviors(){ return [ 'verbs' => [ 'class' => VerbFilter::className(), 'actions' => [ 'mod-avatar'=> ['POST','OPTIONS'], ], ], 'CrossOriginBehavior' => [ 'class' => CrossOriginBehavior::className(), 'actions' => [ 'mod-avatar' ] ] ]; }`
数字派 北京
最后登录:2023-03-07
在线时长:52小时34分
- 粉丝10
- 金钱1515
- 威望10
- 积分2135