我正在尝试将一些 HTTP 请求从我的 angular.js 应用程序发送到我的服务器,但我需要解决一些 CORS 错误。
使用以下代码发出 HTTP 请求:
functions.test = function(foo, bar) {
return $http({
method: 'POST',
url: api_endpoint + 'test',
headers: {
'foo': 'value',
'content-type': 'application/json'
},
data: {
bar:'value'
}
});
};
第一次尝试以一些 CORS 错误告终。所以我在我的 PHP 脚本中添加了以下几行:
header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Methods: POST, GET, OPTIONS, DELETE, PUT');
header('Access-Control-Allow-Headers: X-Requested-With, Content-Type, Origin, Authorization, Accept, Client-Security-Token, Accept-Encoding, X-Auth-Token, content-type');
现在消除了第一个错误。
现在 Chrome 的开发者控制台向我显示以下错误:
angular.js:12011 OPTIONS http://localhost:8000/test (anonymous function)
423ef03a:1 XMLHttpRequest cannot load http://localhost:8000/test. Response for preflight has invalid HTTP status code 400
并且网络请求看起来像我预期的那样(HTTP 状态
400
也是预期的):我无法想象如何解决这个问题(以及如何理解)为什么请求会在本地主机上发送为
OPTIONS
并将远程服务器作为 POST
.有没有办法解决这个奇怪的问题?
最佳答案
TL;DR 答案
解释OPTIONS
请求被称为 pre-flight request ,它是 Cross-origin resource sharing (CORS) 的一部分.浏览器使用它来检查是否允许来自特定域的请求 如下:
POST
请求 application/json
内容类型 OPTIONS
请求相同的 URL 2XX
状态响应,浏览器不会发送实际请求(因为他现在知道无论如何都会被拒绝)HTTP 200 OK
(或任何其他 2XX
)响应,浏览器将发送实际请求 POST
在你的情况下解决方案
因此,在您的情况下,存在正确的标题,您只需要 确保飞行前请求的响应 HTTP 状态代码为
200 OK
或其他一些成功的(2XX
) .详细说明
Simple requests
浏览器 不是 在某些情况下发送飞行前请求,即所谓的简单请求,用于以下情况:
- One of the allowed methods: -
GET
-HEAD
-POST
Accept
Accept-Language
Content-Language
Content-Type
(但请注意下面的附加要求)DPR
Downlink
Save-Data
Viewport-Width
Width
application/x-www-form-urlencoded
multipart/form-data
text/plain
XMLHttpRequestUpload
上注册事件监听器请求中使用的对象;这些是使用 XMLHttpRequest.upload
访问的。属性(property)。 ReadableStream
请求中使用了对象。 这样的请求是直接发送的,服务器只是成功地处理了请求,或者在它与 CORS 规则不匹配的情况下回复错误。在任何情况下,响应都将包含 CORS header
Access-Control-Allow-*
.Pre-flighted requests
浏览器 是 如果实际请求不满足简单请求条件,则发送飞行前请求,最常见的是:
application/xml
或 application/json
等,使用GET
, HEAD
或 POST
POST
方法的内容类型不是 application/x-www-form-urlencoded
, multipart/form-data
或 text/plain
您需要 确保对飞行前请求的响应具有以下属性 :
200 OK
Access-Control-Allow-Origin: *
(通配符 *
允许来自任何域的请求,当然您可以使用任何特定域来限制访问)从另一边,服务器可能 拒绝 CORS 请求 只需通过以下属性发送对飞行前请求的响应:
2XX
除外)200 OK
),但没有任何 CORS header (即 Access-Control-Allow-*
)见documentation on Mozilla Developer Network或例如 HTML5Rocks' CORS tutorial详情。
关于javascript - 来自 Angular 的 HTTP 请求作为 OPTIONS 而不是 POST 发送,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40497399/