Access-Control-Allow-Origin错误但请求通过

时间:2015-09-01 18:29:53

标签: angularjs laravel-5 cors

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

我从AngularJS前端到Laravel 5(+ laravel-cors)后端进行通信。

我开始使用简单的jQuery AJAX调用(下面)进行测试,当我从本地Vagrant环境(http://dev.example.local/test.html)向http://api.example.com/v1/matches发出请求时,我收到有关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服务测试人员这样的工具正确执行请求,并且数据添加没有错误。

欢迎任何关于如何进一步调试这个问题的想法......我一直试图整理这一天,我不知道是什么造成了什么它

1 个答案:

答案 0 :(得分:8)

您的服务器必须在响应中返回适当的Access-Control-Allow-Origin标头。例如,如果请求是从http://stackoverflow.com发送的,那么您的服务器必须返回此标头:Access-Control-Allow-Origin: http://stackoverflow.com。您可以通过查看请求中的Origin标头来确定服务器端的原点。如果您的服务器在响应中返回此标头,则您将无法访问响应浏览器端的属性(例如状态代码,标头或邮件正文)。 Same Origin Policy是此限制的核心。

当Postman或PhpStorm的RESTful服务测试人员发送请求时,您没有看到任何类似问题的原因是这些服务发送{{1带有请求的标头,因为它们不受同源策略的约束。默认情况下,浏览器会将此标头附加到任何跨源的ajax请求,因为浏览器 受同源策略的约束。在我之前的场景中,请求标头如下所示:Origin。实现the CORS spec的浏览器需要添加此请求标头,以便服务器能够确定请求的来源是否已针对跨源Ajax请求列入白名单。如果是这种情况,服务器将返回正确的Origin: http://stackoverflow.com标头。如果没有,它可以简单地省略标题。没有实现CORS规范的浏览器将拒绝发送这样的ajax请求。

关于你为什么要首先发送请求的困惑,这归结为&#34;简单&#34;和&#34;非简单&#34; CORS请求。对于简单的CORS请求,请求将始终发送到服务器,但如果没有来自服务器的正确确认,客户端/ JS将无法解析响应。有些CORS请求简单,可以这么说。例如,Access-Control-Allow-OriginDELETE请求或PATCH / POST请求包含非标准标头(例如X-header或GET &#34; application / json&#34;而不是&#34; multipart / form-data&#34;)。换句话说,如果请求在没有JavaScript的情况下无法发送,则简单。例如,Content-Type提交或来自<form>的GET请求将始终发送&#34;简单&#34;要求。对于非简单请求,浏览器必须&#34;预检&#34;请求。这意味着浏览器在原始请求之前发送一个称为预检的中间请求。此预检请求是<script src="...">请求。服务器必须在对此预检的响应中返回标头,以确认原始请求的任何非标准属性。如果是,则浏览器将发送原始请求。

您可以在MDN上了解有关预检和CORS的更多信息。