对预检请求的响应未通过访问控制检查 Laravel 和 Ajax 调用

Response to preflight request doesn't pass access control check Laravel and Ajax call

我在 Laravel 5.1 中创建了一个 REST api 托管在远程服务器上。现在,我',试图从另一个网站(我在本地拥有)使用 API。

在 Laravel 中,我设置了发送 CORS 所需的行 headers。我还使用 Postman 测试了 API,一切似乎都正常!

在前端

然后,我在网站上使用 ajax 发送了 POST 请求,代码如下:

var url="http://xxx.xxx.xxx.xxx/apiLocation";
var data=$("#my-form").serialize();
    $.ajax({
                    type: "POST",
                    url: url,
                    data: data,
                    headers: { 'token': 'someAPItoken that I need to send'},
                    success: function(data) {
                        console.log(data);
                    },
                    dataType: "json",
                }); 

购买然后我在控制台中收到此错误:

XMLHttpRequest cannot load http://xxx.xxx.xxx.xxx/apiLocation. Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost' is therefore not allowed access.

在后端

在 API 中我设置了这个(使用 Laravel 中间件来设置 headers):

return $next($request)
            ->header('Access-Control-Allow-Origin', '*')
            ->header('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS');

所以,我对问题到底出在哪里感到困惑。

  1. 在服务器里?但是为什么 Postman 可以正常工作?
  2. 是否在Ajax通话中?那么,那我应该补充什么呢?

您的后端代码必须包含对 OPTIONS 请求的一些显式处理,这些请求仅使用配置的 header 发送 200 响应;例如:

if ($request->getMethod() == "OPTIONS") {
    return Response::make('OK', 200, $headers);
}

server-side 代码还必须发送 Access-Control-Allow-Headers 响应 header,其中包括 token 请求的名称 header 您的前端代码正在发送:

-> header('Access-Control-Allow-Headers', 'token')

but then why with Postman work fine?

Postman 不是网络应用程序,不受浏览器对网络应用程序施加的 same-origin 限制的约束,以阻止它们发出 cross-origin 请求。 Postman 是一个浏览器 bolt-on,可以方便地测试请求,就像在浏览器之外使用 curl 或命令行中的任何方式一样。邮递员可以自由地发出 cross-origin 请求。

https://developer.mozilla.org/docs/Web/HTTP/Access_control_CORS 相反解释了浏览器如何阻止 Web 应用程序发出 cross-origin 请求,以及如何 un-block 浏览器通过配置后端发送正确的 CORS headers.

https://developer.mozilla.org/docs/Web/HTTP/Access_control_CORS#Preflighted_requests 解释了为什么浏览器发送 OPTIONS 请求您的后端需要处理。