Angularjs 访问控制允许源错误,但请求通过

Angularjs 访问控制允许源错误,但请求通过,angularjs,laravel-5,cors,Angularjs,Laravel 5,Cors,我目前正在为我的live服务器部署一个基本API,我遇到了(我认为是)CORS问题,但有一些行为我无法解释 我正在从AngularJS前端到Laravel 5(+)后端进行通信 我开始使用一个简单的jQueryAjax调用(如下)进行测试,当我从本地Vagrant环境发出请求时(http://dev.example.local/test.html)至http://api.example.com/v1/matches我得到一个关于访问控制允许原点的错误。奇怪的是,请求确实通过了,因为信息通过基于L

我目前正在为我的live服务器部署一个基本API,我遇到了(我认为是)CORS问题,但有一些行为我无法解释

我正在从AngularJS前端到Laravel 5(+)后端进行通信

我开始使用一个简单的jQueryAjax调用(如下)进行测试,当我从本地Vagrant环境发出请求时(
http://dev.example.local/test.html
)至
http://api.example.com/v1/matches
我得到一个关于
访问控制允许原点的错误。奇怪的是,请求确实通过了,因为信息通过基于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环境(应用程序)在本地开发了应用程序,它在这些环境中正常工作

一些意见:

  • 在my Chrome Developer Tools中,每个请求都会显示方法:
    POST
    ,状态:
    200 OK
    ,键入:
    xhr
  • Postman和PhpStorm的RESTful service tester等工具可以正确执行请求,并且添加数据时不会出现错误

欢迎提供有关如何进一步调试此问题的任何想法。。。我一整天都在想这个问题,但我不知道是什么原因造成的。

您的服务器必须在响应中返回一个适当的
访问控制允许源文件
标题。例如,如果请求是从发送的,则服务器必须返回此标头:
Access Control Allow Origin:http://stackoverflow.com
。您可以通过查看请求上的
origin
头来确定服务器端的来源。如果服务器未在响应中返回此标头,则您将无法访问响应浏览器端的属性(例如状态代码、标头或消息正文)。这一限制的核心是

当请求由邮递员或PhpStorm的RESTful service tester发送时,您没有看到任何类似问题的原因是,这些服务不随请求发送
来源
头,因为它们不受相同来源策略的约束。默认情况下,浏览器会将此头附加到任何跨源ajax请求,因为浏览器受同一源策略的约束。在我前面的场景中,请求头如下所示:
Origin:http://stackoverflow.com
。需要实现的浏览器添加此请求头,以便服务器能够确定跨源ajax请求的请求源是否已被列入白名单。如果是这种情况,服务器将返回正确的
Access Control Allow Origin
标题。如果不是,它可以省略标题。没有实现CORS规范的浏览器将拒绝发送这样的ajax请求

关于您对为什么首先发送请求的困惑,这归结为“简单”和“非简单”CORS请求之间的区别。对于简单的CORS请求,请求将始终发送到服务器,但是如果没有服务器的正确确认,client/JS将无法解析响应。可以说,有些CORS请求并不简单。例如,这些请求是
DELETE
PATCH
请求,或
POST
/
GET
请求,这些请求包含非标准头(例如X头或
内容类型
“应用程序/json”而不是“多部分/表单数据”)。换句话说,如果没有JavaScript无法发送请求,那么请求就不简单。例如,
提交或来自
的GET请求将始终发送“简单”请求。对于非简单请求,浏览器必须“预飞”请求。这意味着浏览器在原始请求之前发送一个称为预飞行的中间请求。此飞行前请求是一个
OPTIONS
请求。服务器必须在对此预飞行的响应中返回确认原始请求的任何非标准属性的头。如果是,则浏览器将发送原始请求


您可以在上阅读有关预飞行和CORS的更多信息。

我已经知道您所说的大部分内容,但是关于为什么会收到请求的解释对我来说是新的,谢谢!我99%确定后端的
访问控制允许源代码设置为
*
,因为它是一个公共API,有什么方法可以测试它吗?因为我通过jQuery运行AJAX POST请求,所以它们并不简单,对吗?所以他们应该发送飞行前的请求。我应该能够在Chrome devtools的de-Network选项卡中看到这一点,因为我没有看到任何。结果是我错误地实现了laravel cors包或其他东西。我在我的apache2 vhost中添加了
访问控制允许源代码
标题,现在它工作正常了……如果浏览器没有发送预飞行,那么请求是“简单的”。无论您是否使用jQuery发送它们,都没有区别。只有当请求包含我在回答中提到的一些内容时,它们才是非简单的。例如,如果您将jQuery发送的请求的内容类型设置为application/json,那么浏览器将预处理该请求。我链接到的MDN文章更为详细。在你的问题中,你并不清楚你了解什么是CORS,或者你已经尝试返回一个正确的CORS头了。我现在知道你提到了拉瓦瓦·科尔斯,没问题。谢谢你的详细解释,它确实刷新了我对CORS的记忆。多亏了你的回答,我最终对它进行了测试,所以我会将它标记为已接受。