CORS是一个W3C标准,全称是"跨域资源共享"(Cross-origin resource sharing)。我们知道,用浏览器发送 http 请求(ajax)就存在跨域的问题,现在主流的解决跨域方案就是 CORS。
这里特别强调,我们经常说的跨域只是浏览器的限制,如果我们用脚本发送请求或者通过服务器请求,都不不会有跨域问题,这其中主要原因是浏览器使用门槛非常低,为了防止别有用心的人攻击普通用户,所以引入跨域策略
CORS是 W3C 在2014年1月16日发布的一个正式推荐的通信标准,主要解决用户代理的Web应用通过Ajax或者其他机制从另一个站点访问资源、获取数据的问题。
前提: 服务端需要添加支持CORS的相关功能,即设定http的 Access-Control-Allow-Origin 允许的值
CORS的通信都由浏览器完成,不需要用户参与。默认浏览都是通过Ajax通信,如果浏览器在发送请求时监测到当前请求跨域了,就会自动转成CORS
CORS 和 Ajax 区别
CORS 和 Ajax 在发送请求时没有任何区别,都是http请求,唯一区别就是 CORS 请求时,会在 http请求头 header 中添加几个关键词,用来表示当前请求是跨域请求。
浏览器将CORS请求分成两类:简单请求和非简单请求
只要同时满足以下两大条件,就属于简单请求。
条件一:
条件二:
简单请求就是浏览器直接发送一个CORS请求(ajax请求)。发送之前,浏览器会给本次http请求添加一个请求头 Origin
上面的头信息中, Origin 字段用来说明,本次请求来自哪个源(协议 + 域名 + 端口)。服务器根据这个值,决定是否同意这次请求。
我们看一个时许图(本人开发的一个在线时序图工具 http://sizhuiit.com:9989/static/ )
非简单请求就是再发送请求前先发送一个 OPTIONS 请求,提前检测一下请求是否被允许,主要目的是为了防止跨域请求对后台数据的破坏或盗取,简单请求安全性较低,服务器是处理了请求后再返回数据,非简单请求模式下,服务器在提前检测时不应该处理请求。
跨域资源共享( CORS )是一种机制,是W3C标准。它允许浏览器向跨源服务器,发出 XMLHttpRequest 或 Fetch 请求。并且整个 CORS 通信过程都是浏览器自动完成的,不需要用户参与。
而使用这种 跨域资源共享 的前提是,浏览器必须支持这个功能,并且服务器端也必须同意这种 "跨域" 请求。因此实现 CORS 的关键是服务器需要服务器。通常是有以下几个配置:
具体可看: https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Access_control_CORS#Preflighted_requests
过程分析:
另外在 CORS 中有 简单请求 和 非简单请求 ,简单请求是不会触发 CORS 的预检请求的,而非简单请求会。
“需预检的请求” 要求必须首先使用 OPTIONS方法发起一个预检请求到服务器,以获知服务器是否允许该实际请求。"预检请求“的使用,可以避免跨域请求对服务器的用户数据产生未预期的影响。
简单请求不会触发 CORS 的预检请求,若请求满足所有下述条件,则该请求可视为“简单请求”:
简单回答 :
详细回答 :
除了上面这些请求外,都是非简单请求。
若是跨域的非简单请求的话,浏览器会首先向服务器发送一个预检请求,以获知服务器是否允许该实际请求。
整个过程大概是:
这里有两点要注意:
一:
Access-Control-Request-Method 没有 s
Access-Control-Allow-Methods 有 s
二:
关于 Access-Control-Max-Age ,浏览器自身也有维护一个最大有效时间,如果该首部字段的值超过了最大有效时间,将不会生效,而是以最大有效时间为主。
还是在原本 JSONP 的那个案例上。
我在根目录下新建了一个文件夹 cors ,并往里面添加了一个 index.html 文件:
/cors/index.html
为了后面也方便调试,用 node 简单写了一个前端的本地服务和后端的本地服务。
在根目录下新建 client.js 文件,并写入:
./client.js :
在根目录下新建 index.html 文件,并写入:
./index.html :
(以上:实现了一个简单的前端路由效果)
在根目录下新建 server.js 文件,并写入:
./server.js :
并给 package.json 中配置两个启动指令:
package.json :
OK
欢迎分享,转载请注明来源:夏雨云
评论列表(0条)