> 是不是项目中每个跨域api接口(几乎全部都是)都得做同样OPTIONS的路由?
你可以直接在中间件里判断下当前是否是options请求,如果是则直接返回跨域header,不继续执行正常逻辑。这样就不用每个接口都设置options路由。中间件代码类似如下:
class AccessControl implements MiddlewareInterface
{
public function process(Request $request, callable $next) : Response
{
/** @var Response $response */
if ($request->method() == 'OPTIONS') {
response = response('');
} else {
$response = $next($request);
}
$response->withHeaders([
'Access-Control-Allow-Origin' => '*',
'Access-Control-Allow-Methods' => 'GET,POST,PUT,DELETE,OPTIONS',
'Access-Control-Allow-Headers' => 'Content-Type,Authorization,X-Requested-With,Accept,Origin',
]);
return $response;
}
}
再说说options请求
浏览器在特定情况下才会发起opitons请求。
1. 使用了下面任一HTTP 方法:
PUT/DELETE/CONNECT/OPTIONS/TRACE/PATCH
2. 人为设置了以下集合之外首部字段:
Accept/Accept-Language/Content-Language/Content-Type/DPR/Downlink/Save-Data/Viewport-Width/Width
3. Content-Type 的值不属于下列之一:
application/x-www-form-urlencoded、multipart/form-data、text/plain
一般情况下ajax请求不会触发options请求。我这里经过测试,在ajax里参数设置contentType:'application/json'时,会触发options请求。
$.ajax({
url : '地址',
type : "post",
contentType:'application/json', // 这里
success : function(response){},
error : function (err) {}
});
如果你的项目发起了options请求,可以看下是符合哪个条件触发的,是否可以避免。