在 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.
近期评论