在 Yii2 中,当服务端异常时,未响应 500,而是在浏览器中提示:CORS 错误
1、在 Yii2 中,当服务端异常时,未响应 500,而是在浏览器中提示:CORS 错误,进而导致用户体验上,前端一直加载中。控制台中提示如下,如图1
Access to XMLHttpRequest at 'https://api.apply.local/convention-free-field/get-search-condition-fields-by-convention-id' from origin 'https://console.apply.local' has been blocked by CORS policy: The 'Access-Control-Allow-Origin' header contains multiple values 'https://console.apply.local, *', but only one is allowed.
2、现有的逻辑是在浏览器中,前端通过 JS 请求后端的 API。因此,防止 CORS 问题,后端实现如下
public static function setAllowOrigin()
{
$httpOrigin = $_SERVER['HTTP_ORIGIN'] ?? '';
Yii::debug('OPTION CHECK: ' . $httpOrigin);
if (
in_array($httpOrigin, [
//
'http://console.apply.local',
'https://console.apply.local',
'http://tougao.apply.local',
'https://tougao.apply.local',
'http://apply.local',
'https://apply.local',
'http://official.local',
'http://localhost:8080',
'http://localhost:8081',
'http://localhost:8082',
'http://localhost:8083',
'http://localhost:8084',
//正式域名
])
) {
\Yii::$app->response->headers->add('Access-Control-Allow-Origin', $httpOrigin);
\Yii::$app->response->headers->add('Access-Control-Allow-Headers', '*');
}
}
self::setAllowOrigin();
3、仔细分析请求的响应头,access-control-allow-origin: *,覆盖了 setAllowOrigin 方法中设置的 access-control-allow-origin: https://console.apply.local。 如图2
4、决定将第二步骤的方法 setAllowOrigin 全部注释掉,避免大量的注释 self::setAllowOrigin();
public static function setAllowOrigin()
{
// $httpOrigin = $_SERVER['HTTP_ORIGIN'] ?? '';
// Yii::debug('OPTION CHECK: ' . $httpOrigin);
// if (
// in_array($httpOrigin, [
// //
// 'http://console.apply.local',
// 'https://console.apply.local',
// 'http://tougao.apply.local',
// 'https://tougao.apply.local',
// 'http://apply.local',
// 'https://apply.local',
// 'http://official.local',
// 'http://localhost:8080',
// 'http://localhost:8081',
// 'http://localhost:8082',
// 'http://localhost:8083',
// 'http://localhost:8084',
// //正式域名
// ])
// ) {
// \Yii::$app->response->headers->add('Access-Control-Allow-Origin', $httpOrigin);
// \Yii::$app->response->headers->add('Access-Control-Allow-Headers', '*');
// }
}
self::setAllowOrigin();
5、在所有 API 控制器的基类中集中配置
public function behaviors()
{
$behaviors = parent::behaviors();
$behaviors['corsFilter'] = [
'class' => Cors::class,
'cors' => [
'Origin' => [
//
'http://console.apply.local',
'https://console.apply.local',
'http://tougao.apply.local',
'https://tougao.apply.local',
'http://apply.local',
'https://apply.local',
'http://official.local',
'http://localhost:8080',
'http://localhost:8081',
'http://localhost:8082',
'http://localhost:8083',
'http://localhost:8084',
//正式域名
],
'Access-Control-Allow-Headers' => ['*'],
],
];
return $behaviors;
}
6、当服务端异常时,未在浏览器中提示:CORS 错误。而是正常响应,符合预期。如图3
7、查看响应头,access-control-allow-origin: https://console.apply.local 。符合预期。如图4
8、当前端的网址不在 Origin 的配置项中时,提示:CORS 错误,符合预期。
Access to XMLHttpRequest at 'https://api.apply.local/convention-free-field/get-search-condition-fields-by-convention-id' from origin 'https://console.apply.local' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.




近期评论