对预检请求的响应未通过访问控制检查Laravel和Ajax调用 [英] Response to preflight request doesn't pass access control check Laravel and Ajax call

查看:108
本文介绍了对预检请求的响应未通过访问控制检查Laravel和Ajax调用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在远程服务器上托管了一个用Laravel 5.1制作的REST API.现在,我正在尝试从另一个网站(我在本地拥有)使用该API.

在Laravel中,我设置了必要的行以发送CORS标头.我还使用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无法加载 http://xxx.xxx.xxx.xxx/apiLocation . 对预检请求的响应未通过访问控制检查:否 请求中存在"Access-Control-Allow-Origin"标头 资源.因此,不允许访问来源" http://localhost ".

在后端

在API中,我对此进行了设置(使用Laravel中间件设置标头):

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

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

  1. 在服务器中?但是为什么与邮递员一起工作还可以呢?
  2. 是否在Ajax通话中?所以,那我应该添加什么?

解决方案

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

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

服务器端代码还必须发送Access-Control-Allow-Headers响应标头,其中包括您的前端代码正在发送的token请求标头的名称:

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

但是那为什么与Postman一起工​​作正常呢?

因为Postman不是网络应用,并且不受浏览器对网络应用的同源政策限制,以限制他们发出跨域请求. Postman是浏览器的附加组件,以方便的方式测试请求,就像可以使用curl或命令行中的其他命令在浏览器之外发出请求一样.邮递员可以自由发出跨域请求.

https://developer.mozilla.org/zh-CN相比之下,/docs/Web/HTTP/Access_control_CORS 解释了浏览器如何阻止Web应用发出跨域请求,还说明了如何通过配置后端发送正确的CORS标头来取消阻止浏览器执行此操作. /p>

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

I have a REST api made in Laravel 5.1 hosted in a remote server. Now, I', trying to consume that API from another website (that I have in local).

In Laravel I set the required lines to send the CORS headers. I also tested the API using Postman and everything seems to be ok!

In the Frontend

Then, in the website I sent the POST request using ajax, with this code:

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",
                }); 

Buy then I get this error in the console:

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.

In the Backend

In the API I set this (using a Laravel Middleware to set the headers):

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

So, I'm confused about where is exactly the problem.

  1. In the server? but then why with Postman work fine?
  2. Is in the Ajax call? so, then what should I add?

解决方案

Your backend code must include some explicit handling for OPTIONS requests that sends a 200 response with just the configured headers; for example:

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

The server-side code also must send an Access-Control-Allow-Headers response header that includes the name of the token request header your frontend code is sending:

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

but then why with Postman work fine?

Because Postman isn’t a web app and isn’t bound by the same-origin policy restrictions browsers place on web apps to restrict them from making cross-origin requests. Postman is a browser bolt-on for convenience of testing requests in the same way they could be made outside the browser using curl or whatever from the command line. Postman can freely make cross-origin requests.

https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS in contrast explains how browsers block web apps from making cross-origin requests but also how you can un-block browsers from doing that by configuring your backend to send the right CORS headers.

https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS#Preflighted_requests explains why the browser is sending that OPTIONS request your backend needs to handle.

这篇关于对预检请求的响应未通过访问控制检查Laravel和Ajax调用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆