基础环境
Laravel:9.5.1
php:8.1
前端项目访问地址:http://127.0.0.1
后端项目访问地址:http://127.0.0.1:8090
问题描述
在用 Laravel 开发 api 接口的时候,在 nginx 配置了允许跨域 add_header Access-Control-Allow-Origin *;
但是在前端使用 VUE 跨域调用我的 api 的时候,提示跨域配置重复定义的错误,如下:
Access to XMLHttpRequest at 'http://127.0.0.1:8090/api/disk/search?word=java&page=1×tamp=1649492320000' from origin 'http://127.0.0.1' has been blocked by CORS policy: The 'Access-Control-Allow-Origin' header contains multiple values '*, *', but only one is allowed.
通过对访问标头的查看,可以发现有两个跨域的配置:
Access-Control-Allow-Origin: *
Access-Control-Allow-Origin: *
解决方案
分析原因
通过查询,实际上是由于 fruitcake/laravel-cors
包导致的错误。在 Laravel 中如果 prefix 为 api 则自动添加跨域的 header 头。
在 vendor\Fruitcake\Cors\CorsService
中,有这样一段代码,可以看到对 header 的操作。
private function configureAllowedOrigin(Response $response, Request $request): void
{
if ($this->allowAllOrigins === true && !$this->supportsCredentials) {
// Safe+cacheable, allow everything
$response->headers->set('Access-Control-Allow-Origin', '*');
} elseif ($this->isSingleOriginAllowed()) {
// Single origins can be safely set
$response->headers->set('Access-Control-Allow-Origin', array_values($this->allowedOrigins)[0]);
} else {
// For dynamic headers, set the requested Origin header when set and allowed
if ($this->isCorsRequest($request) && $this->isOriginAllowed($request)) {
$response->headers->set('Access-Control-Allow-Origin', (string) $request->headers->get('Origin'));
}
$this->varyHeader($response, 'Origin');
}
}
解决过程
在 App\Http\Kernel
中,只需要注释掉 HandleCors::class
就可以解决问题。
protected $middleware = [
// ... 此处略去 ...
// \Illuminate\Http\Middleware\HandleCors::class,
// ... 此处略去 ...
];
然后再次请求,就OK了。