Axios 请求:被 CORS 策略阻止

Axios Request: Blocked by CORS Policy

在laravel 5.8、/ "vue": "^2.5.17" / "axios": "^0.18"中,我需要读取从postman ok读取的外部数据: https://imgur.com/a/SRBmK0P

我尝试使用 axios 读取这些数据但出现错误: https://imgur.com/a/o97xLm7

在浏览中,我看到了请求的详细信息: https://imgur.com/a/EUkyV43

我的JS代码:

            axios.post(window.REMOTE_SEARCH_WEB, {
                "query": "pc gamers",
                "blogger": false,
                "company": false,
                "influencer": false,
                "article": false,
                "pageId": 1,
                "sort": null,
                "sortOrder": null,
                "searchType": 1,
                "Access-Control-Allow-Origin": this.app_url,
                "Access-Control-Allow-Methods": "POST",
                "Access-Control-Max-Age": 86400,
                "Access-Control-Allow-Headers": "Content-Type, Authorization",
                'Access-Control-Allow-Credentials': 'true'
            }).then((response) => {

其中 this.app_url 是应用 运行 所在网站的首页 url

谷歌搜索我发现有几个参数Access-Control-*必须填写,就像上面的代码一样,但这对我没有帮助。

你能告诉我怎么解决吗?

是否可以从我的带有 axios 的 js 代码到我控制中的 运行 操作并从那里使用 PHP/Laravel 发出请求来做出决定?如果是,请提供此类决定的示例...

修改块: 我安装了 https://github.com/barryvdh/laravel-cors 软件包和

1) 在文件中我在 app/Http/Kernel.php

中添加了行
protected $middleware = [
    // ...
    \Barryvdh\Cors\HandleCors::class,
];

我在中间件组I中添加的不是'/api'内部,而是外部请求。 正确吗?

2) 我没有更改文件 config/cors.php:

return [

    'supportsCredentials' => false,
    'allowedOrigins' => ['*'],
    'allowedOriginsPatterns' => [],
    'allowedHeaders' => ['*'],
    'allowedMethods' => ['*'],
    'exposedHeaders' => [],
    'maxAge' => 0,

];

3) 在 axios.post 请求中我删除了所有访问控制参数

axios.post(window.REMOTE_SEARCH_WEB, {
    "query": "pc gamers",
    "blogger": false,
    "company": false,
    "influencer": false,
    "article": false,
    "pageId": 1,
    "sort": null,
    "sortOrder": null,
    "searchType": 1,
}).then((response) => {

4) 但是在请求中出现同样的错误:https://imgur.com/a/wbgmrps

怎么了?

谢谢!

您可以通过在后端创建一个拦截器中间件来解决它,它将 Access-control-allow headers 附加到请求。

创建中间件cors

public function handle($request, Closure $next)
    {
        return $next($request)
          ->header('Access-Control-Allow-Origin', '*') //REPLACE STAR WITH YOUR URL
          ->header('Access-Control-Allow-Methods', 'GET, POST, PUT, PATCH, DELETE, OPTIONS')
          ->header('Access-Control-Allow-Headers', 'content-type, authorization, x-requested-with');
    }

然后在app/http/kernel.php

全局中间件列表中列出中间件
 protected $middleware = [
             ...
             \App\Http\Middleware\Cors::class
]

您找到的关于 CORS 通信的 headers 的所有信息都是正确的,但必须在您使用的 API 服务器上设置,而不是在您调用的服务器上设置。

您试图在您的 ajax 调用中添加那些 headers 并安装了 laravel-cors 包,但是它们都安装在调用服务器上(一个是客户端javascript,另一个是 laravel 上的服务器端)。

希望您可以控制您使用 laravel/vue 应用程序使用的 api 服务器,您要做的第一件事就是在所有 [=52] 上添加此 header =] 回复:

header('Access-Control-Allow-Origin: <insert calling domain here>')
header('Access-Control-Allow-Methods: GET, PUT, POST, DELETE, OPTIONS');  // Use only the methods you are using

在开发模式下,您可以只使用 Access-Control-Allow-Origin: *,但强烈建议在生产环境中使用正确的域。您可以对部分网址使用通配符,但如果您不使用 80/443,请记住指定端口。 (例如 Access-Control-Allow-Origin: *.mydomain.com:8080.

但是这还不够,默认情况下 laravel 在他的 app.js 中包含 bootstrap.js 库,这导致在所有ajax 使用 axios 进行的调用。这是 resources\js\bootstrap.js 中负责此的源代码部分:


/**
 * We'll load the axios HTTP library which allows us to easily issue requests
 * to our Laravel back-end. This library automatically handles sending the
 * CSRF token as a header based on the value of the "XSRF" token cookie.
 */

window.axios = require('axios');

window.axios.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest';

/**
 * Next we will register the CSRF Token as a common header with Axios so that
 * all outgoing HTTP requests automatically have it attached. This is just
 * a simple convenience so we don't have to attach every token manually.
 */

let token = document.head.querySelector('meta[name="csrf-token"]');

if (token) {
    window.axios.defaults.headers.common['X-CSRF-TOKEN'] = token.content;
} else {
    console.error('CSRF token not found: https://laravel.com/docs/csrf#csrf-x-csrf-token');
}

这里是我刚刚从 laravel 发起的 axios 调用的 header

如您所见,必须在 api 服务器上指定 2 个 header 才能使 CORS 正常工作。这是您应该添加的第三个设置:

header('Access-Control-Allow-Headers: X-CSRF-TOKEN, X-Requested-With');

你可能还有更多的header要设置,只需检查你的调用并添加全部,如果你忘记了其中任何一个,它将在浏览器控制台。但请注意不要使用通配符 *,因为此处不支持它。

如果您无法控制 API 服务器,那么事情就变得复杂了。

如果 api 服务器已经支持 Access-Control-Allow-Origin:* 那么您可以从 bootstrap.js 中删除 X-CSRF-TOKEN 和 X-Requested-With header ,但是要小心,因为这些用于从 vue 到 laravel 后端的内部 api 调用。

或者,您可以使用与您的 laravel 服务器具有相同域的代理,或者您可以使用您的 laravel 服务器为您进行 api 调用。

CORS 从服务器端被阻止。所以你需要从服务器端启用它。

但绝不允许所有来源,这对安全性不利

而是只允许您从中触发 API 的域。

如何启用?

点这里CORS