Axios请求:被CORS政策阻止

时间:2019-05-14 14:54:58

标签: java laravel-5 access-control

在laravel 5.8 / "vue": "^2.5.17" / "axios": "^0.18"中,我需要读取从邮递员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

怎么了?

谢谢!

3 个答案:

答案 0 :(得分:1)

您可以通过在后端创建拦截器中间件来解决该问题,该中间件会将Access-control-allow标头附加到请求。

创建中间件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
]

答案 1 :(得分:0)

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

您试图将这些标头添加到进行的ajax调用中并安装了laravel-cors软件包,但是这些标头都安装在了调用服务器上(一个是javascript的客户端,另一个是laravel的服务器端)。

希望您可以控制要使用laravel / vue应用程序使用的api服务器,首先应该在所有api响应上添加此标头:

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: *,但是强烈建议在生产环境中使用正确的域。您可以将通配符用于部分URL,但是,如果不使用80/443,请记住指定端口。 (例如Access-Control-Allow-Origin: *.mydomain.com:8080

但这还不够,默认情况下,laravel在他的app.js中包含bootstrap.js库,这会导致在用axios进行的所有ajax调用中包含CSRF令牌头。这是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调用的标题 axios call

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

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

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

如果您对API服务器没有控制权,那么它将变得很复杂。

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

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

答案 2 :(得分:0)

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

但永远不要允许所有来源,这对安全不利

相反,只允许您从中触发 API 的域。

如何启用?

点击此处CORS