最近由于申请到了新的服务器域名, 需要慢慢把一些服务和应用的旧域名逐渐迁到新的域名来, 迁移工作涉及到前端以及后台API, 更多可能是一些运维设置和跨域的问题, 接下来要老生常谈一下CORS, 就当复习吧..
Cross-Origin Resource Sharing (CORS)
Cross-Origin Resource Sharing (CORS), 是浏览器跨源服务器进行资源共享的一个标准, 是解决跨越访问的方法之一.
那什么是跨域呢?
举个例子, 如果你的网页处于a.niko
域名下, 若使用ajax访问b.niko
下的资源, 就会有跨域的问题. 如果b.niko
不允许a.niko
的资源请求, 那么这个请求将会失败.
实例演示
首先建立nginx实验环境, 来模拟跨域的问题, 编辑nginx的配置, 建立两个server :
a.niko
服务器
server { |
b.niko
服务器
server { |
当然/etc/hosts
记得加入这两个域名.
接着打开a.niko
的页面, 页面中的js会使用ajax请求b.niko
的某一资源, 这时浏览器会提示不允许跨域请求, 如下:
使用CORS解决跨域
如果要解决这个问题, 只需要在服务器的响应头加一个header: Access-Control-Allow-Origin
.
在nginx中是这样设置:
server { |
其中的值填写Origin域名, *
号表示所有.
然后刷新页面, 查看跨域请求的结果:
如上, 跨域请求成功, 可以看Origin
和Access-Control-Allow-Origin
header.
为什么POST前有一个OPTIONS请求
这次改为POST方法试一下, 使用ajax-POST
请求b.niko
的资源, 观察请求:
你会看到第一个发出去的是OPTIONS
方法的请求, 而不是POST
.
为什么呢?
这个OPTIONS
请求其实叫做是CORS preflight request
, 作用是在真正的请求发往服务器前, 向服务器确认是否有权限去做这个请求。
根据CORS的规范, Content-Type
非application/x-www-form-urlencoded, multipart/form-data, or text/plain
的POST请求会进行preflight
.
下面的链接会有更详细的介绍哪些请求会进行preflight:
Types of CORS requests
如果需要对这个OPTIONS
请求进行特殊处理, nginx设置如下:
location / { |
如上, response的header除了Access-Control-Allow-Origin
, 还有其他跨域相关的header(Access-Control-Allow-Origin
/ Access-Control-Allow-Methods
/ Access-Control-Allow-Headers
等等), 用以告诉客户端请求跨域访问时的条件和规则, 相关说明可查阅CORS规范文档。
最后
我们都知道, 上面的场景是属于能够控制跨域服务器的情况, 因此可以通过CORS解决跨域问题。
否则, 只能通过JSONP和代理等其他方式来实现, 有兴趣的童鞋可以了解一下, 这里不再赘述.
参考
https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS
http://www.html5rocks.com/en/tutorials/cors/
http://www.itnose.net/detail/6501161.html