为什么即使设置Access-Control-Allow-Origin为*,多个OPTIONS请求仍会被发送?

8
我已经创建了一个API(api.example.com),并希望能够从www.example.com访问。我还希望它可以从其他域名访问。因此,我添加了Access-Control-Allow-Origin:*。但是,当我打开www.example.com时,在所有API请求之前发送了一个预检请求(OPTIONS请求)。 我应该如何停止多个预检请求?我认为应该只有一个预检请求,我做错了什么!!!?或者浏览器在每次调用之前都必须发送预检请求吗?注意:我不想使用JSONP,因为我正在使其对公众可用Access-Control-Allow-Origin:* OPTIONS调用头
Accept:*/*
Accept-Encoding:gzip,deflate,sdch
Accept-Language:en-US,en;q=0.8
Access-Control-Request-Headers:accept, authorization
Access-Control-Request-Method:GET
AlexaToolbar-ALX_NS_PH:AlexaToolbar/alxg-3.2
Connection:keep-alive
Host:api.touchtalent.biz
Origin:http://www.example.com
Referer:http://www.example.com/artist/52894/pratim-relekar
User-Agent:Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/35.0.1916.114 Safari/537.36

OPTIONS调用响应

Access-Control-Allow-Headers:origin, x-requested-with, content-type, Authorization
Access-Control-Allow-Methods:PUT, GET, POST, DELETE
Access-Control-Allow-Origin:*
Connection:Keep-Alive
Content-Encoding:gzip
Content-Length:163
Content-Type:text/html
Date:Fri, 13 Jun 2014 14:24:55 GMT
Keep-Alive:timeout=5, max=98
Server:Apache/2.2.22 (Ubuntu)
Vary:Accept-Encoding
X-Powered-By:PHP/5.4.6-1ubuntu1.8

GET请求请求头

Accept:application/json, text/plain, */*
Accept-Encoding:gzip,deflate,sdch
Accept-Language:en-US,en;q=0.8
AlexaToolbar-ALX_NS_PH:AlexaToolbar/alxg-3.2
Authorization:Bearer VtQJqaTGd7YFb8Mee6GfiLwiRrUdt2iCp9ITuiUE
Connection:keep-alive
Host:api.touchtalent.biz
Origin:http://www.example.com
Referer:http://www.example.com/artist/52894/pratim-relekar
User-Agent:Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/35.0.1916.114 Safari/537.36

获取请求响应头

Access-Control-Allow-Headers:origin, x-requested-with, content-type, Authorization
Access-Control-Allow-Methods:PUT, GET, POST, DELETE
Access-Control-Allow-Origin:*
Connection:Keep-Alive
Content-Length:1116
Content-Type:application/json
Date:Fri, 13 Jun 2014 14:24:55 GMT
Keep-Alive:timeout=5, max=97
Server:Apache/2.2.22 (Ubuntu)
Status:200
X-Powered-By:PHP/5.4.6-1ubuntu1.8

虽然我不想提供一个URL,因为它会随着开发的进行而改变。但如果可能会有所帮助:http://www.touchtalent.biz/home

更新1:
一旦我删除了Authorization:Bearer VtQJqaTGd7YFb8Mee6GfiLwiRrUdt2iCp9ITuiUE头部,就停止了多次预检请求。但是删除此标头将破坏oauth实现。我仍然需要在不删除自定义头部的情况下防止多次预检请求。我该怎么办?
更新2:
添加Access-Control-Max-Age有所帮助,现在它不会为相同的请求发送预检请求。但对于不同的请求(不同的URL),它会发送多个OPTIONS请求。


可能是CORS Access-Control-Max-Age is ignored的重复问题。 - Ray Nicholus
不是的,我没有添加Access-Control-Max-Age,即使添加它也没有帮助。 - Rahul Prasad
在你的问题中提到这一点会非常有用。 - Ray Nicholus
虽然Access-Control-Max-Age有所帮助,但并没有完全解决问题。 - Rahul Prasad
2个回答

3

1

预检请求是由于您的Content-Type为"application/json"而触发的。最简单的方法是在您的情况下将Content-Type设置为"text/plain"。application/x-www-form-urlencoded Content-Type也是可以接受的,但您当然需要适当地格式化请求负载。

如果在进行此更改后仍然看到预检请求,则Angular可能还会向请求中添加X-header。


将内容类型更新为text/plain并没有起作用。 - Rahul Prasad
这是因为使用了用于oAuth的额外自定义标头。 - Rahul Prasad

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接