我正在从AngularJS前端到Laravel 5(laravel-cors)后端进行通信.
我开始使用简单的jQuery AJAX调用(下面)进行测试,当我从本地Vagrant环境(http://dev.example.local/test.html)向http://api.example.com/v1发出请求时/匹配我收到有关Access-Control-Allow-Origin的错误.奇怪的是,请求确实通过,因为信息正确地通过基于Laravel的API存储在数据库中.
$.ajax({ method: 'POST',url: 'http://api.example.com/v1/players',data: { "username": "username","first_name": "First","last_name": "Last","nickname": "" } }).always(function(r) { console.log(r); });
错误:
XMLHttpRequest cannot load http://api.example.com/v1/players. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://other.example.com' is therefore not allowed access.
console.log(r)返回{readyState:0,responseJSON:undefined,status:0,statusText:“error”}
我使用Homestead VM(API)和Vagrant环境(应用程序)在本地开发了应用程序,它在这些环境中正常工作……
一些观察:
>这些请求中的每一个都显示方法:POST,状态:200 OK,在我的Chrome开发者工具中键入:xhr.
> Postman和PHPStorm的RESTful服务测试工具正确执行请求,数据添加无误.
关于如何进一步调试这个问题的任何想法都是受欢迎的……我一直试图整理这一整天,我只是不知道是什么导致了它.
解决方法
当Postman或PHPStorm的RESTful服务测试程序发送请求时,您没有看到任何类似问题的原因是这些服务不会发送带有请求的Origin标头,因为它们不受同源策略的约束.默认情况下,浏览器会将此标头附加到任何跨源的ajax请求,因为浏览器遵循同源策略.在我之前的场景中,请求标头看起来像这样:Origin:http://stackoverflow.com.实现the CORS spec的浏览器需要添加此请求标头,以便服务器能够确定请求的来源是否已被列入白名单以用于跨源Ajax请求.如果是这种情况,服务器将返回正确的Access-Control-Allow-Origin标头.如果没有,它可以简单地省略标题.没有实现CORS规范的浏览器将拒绝发送这样的ajax请求.
关于为什么首先发送请求的困惑,这归结为“简单”和“非简单”CORS请求之间的区别.对于简单的CORS请求,请求将始终发送到服务器,但是如果没有来自服务器的适当确认,客户端/ JS将无法解析响应.一些CORS请求并不简单,可以这么说.例如,这些是DELETE或PATCH请求,或者包含非标准头文件的POST / GET请求(例如X-headers或Content-Type of“application / json”而不是“multipart / form-data”) .换句话说,如果没有JavaScript就无法发送请求,那么请求就不简单了.例如,< form>提交或来自< script src =“...”>的GET请求将始终发送“简单”请求.对于非简单请求,浏览器必须“预检”请求.这意味着浏览器在原始请求之前发送一个称为预检的中间请求.此预检请求是OPTIONS请求.服务器必须在对此预检的响应中返回标头,以确认原始请求的任何非标准属性.如果是,则浏览器将发送原始请求.
您可以在MDN阅读有关预检和CORS的更多信息.