你可能不知道的CORS跨域资源共享
什么是CORS?
默认情况下,为预防某些而已行为,浏览器的XHR对象只能访问来源于同一个域中的资源。我们在日常实际开发中,常常会遇到跨域请求的需求,就出现了一种跨域请求的方案CORS(Cross-Origin Resource Sharing)跨域资源共享。
CORS背后的原理是使用自定的HTTP头部与服务器进行沟通,从而由服务器决定响应是否成功。
了解下同源策略
- 源(origin)就是协议、域名和端口号;
- 同源 就是源相同,即协议、域名和端口完全相同;
- 同源策略同源策略是浏览器的一个安全功能,不同源的客户端脚本在没有明确授权的情况下,不能读写对方资源;
- 同源策略的分类
- DOM 同源策略即针对于DOM,禁止对不同源页面的DOM进行操作;如不同域名的 iframe 是限制互相访问。
- XMLHttpRequest 同源策略禁止使用 XHR 对象向不同源的服务器地址发起 HTTP 请求。
- 不受同源策略限制
- 页面中的链接,重定向以及表单提交(因为表单提交,数据提交到action域后,本身页面就和其没有关系了,不会管请求结果,后面操作都交给了action里面的域)是不会受到同源策略限制的。
- 资源的引入不受限制,js不能读写加载的内容如嵌入到页面中的<script src="..."></script>,<img>,<link>,<iframe>等
为什么要跨域限制
- 如果没有 DOM 同源策略那么就没有啥xss的研究了,因为你的网站将不是你的网站,而是大家的,谁都可以写个代码操作你的网站界面
- 如果没有XMLHttpRequest 同源策略,那么就可以很轻易的进行CSRF(跨站请求伪造)攻击
- 用户登录了自己的网站页面 a.,cookie中添加了用户标识。
- 用户浏览了恶意页面 b.,执行了页面中的恶意 AJAX 请求代码。
- b. 向 a.发起 AJAX HTTP 请求,请求会默认把 a.对应cookie也发送过去。
- a.从发送的 cookie 中提取用户标识,验证用户无误,response 中返回请求数据;数据就泄露了。而且由于Ajax在后台执行,这一过程用户是无法感知的。
- (附)有了XMLHttpRequest 同源策略就可以限制CSRF攻击?别忘了还有不受同源策略的表单提交和资源引入,(安全问题下期在研究)
跨域决解方案
- JSONP 跨域借鉴于 script 标签不受浏览器同源策略的影响,允许跨域引用资源;可以通过动态创建 script 标签,然后利用 src 属性进行跨域;
- 缺点
- 所有网站都可以拿到数据,存在安全性问题,需要网站双方商议基础token的身份验证。
- 只能是GET,不能POST。
- 可能被注入恶意代码,篡改页面内容,可以采用字符串过滤来规避此问题。
- 服务器代理浏览器有跨域限制,服务器不存在跨域问题,所以可以由服务器请求所要域的资源再返回给客户端。
- document.domain、window.name 、location.hash借助于iframe决解DOM同源策略
- postMessage决解DOM同源策略,新方案
- CORS(跨域资源共享)这里讲的重点
CORS(跨域资源共享)
- HTML5 提供的标准跨域解决方案,是一个由浏览器共同遵循的一套控制策略,通过HTTP的Header来进行交互;主要通过后端来设置CORS配置项。
CORS简单使用
之前说得CORS跨域,嗯嗯,后端设置Aess-Control-Allow-Origin|[或具体的域名]就好了;
第一次尝试
app.use(async(ctx,next) => { ctx.set({ "Aess-Control-Allow-Origin": "http://localhost:8088" })
发现有些请求可以成功,有些还是会报错
请求被同源策略阻止,预请求的响应没有通过检查http返回的不是ok?
并且发现发送的是OPTIONS请求:
发现CORS规范将请求分为两种类型,一种是简单请求,一种是带预检的非简单请求
简单请求和非简单请求
浏览器发送跨域请求判断方式
- 浏览器在发送跨域请求的时候,会先判断下是简单请求还是非简单请求,如果是简单请求,就先执行服务端程序,然后浏览器才会判断是否跨域;
- 而对于非简单请求,浏览器会在发送实际请求之前先发送一个OPTIONS的HTTP请求来判断服务器是否能接受该跨域请求;如果不能接受的话,浏览器会直接阻止接下来实际请求的发生。
什么是简单请求
1、请求方法是如下之一
- GET
- HEAD
- POST
2、所有的Header都只包含如下列表中(没有自定义header)
- Cache-Control
- Content-Language
- Content-Type
- Expires
- Last-Modified
- Pragma
除此之外都是非简单请求
CORS非简单请求配置须知
正如上图报错显示,对于非简单请求,浏览器会先发送options预检,预检通过后才会发送真是的请求;
发送options预检请求将关于接下来的真实请求的信息给服务器
Origin请求的源域信息
Aess-Control-Request-Method接下来的请求类型,如POST、GET等
Aess-Control-Request-Headers接下来的请求中包含的用户显式设置的Header列表
服务器端收到请求之后,会根据附带的信息来判断是否允许该跨域请求,通过Header返回信息
Aess-Control-Allow-Origin允许跨域的Origin列表
Aess-Control-Allow-Methods允许跨域的方法列表
Aess-Control-Allow-Headers允许跨域的Header列表,防止遗漏Header,建议没有特殊需求的情况下设置为
Aess-Control-Expose-Headers允许暴露给JavaScript代码的Header列表
Aess-Control-Max-Age最大的浏览器预检请求缓存时间,单位为s
CORS完整配置
koa配置CORS跨域资源共享中间件
const cors = (origin) => { return async (ctx, next) => { ctx.set({ "Aess-Control-Allow-Origin": origin, //允许的源 }) // 预检请求 if (ctx.request.method == "OPTIONS") { ctx.set({ 'Aess-Control-Allow-Methods': 'OPTIONS,HEAD,DELETE,GET,PUT,POST', //支持跨域的方法 'Aess-Control-Allow-Headers': '', //允许的头 'Aess-Control-Max-Age':10000, // 预检请求缓存时间 // 如果服务器设置Aess-Control-Allow-Credentials为true,那么就不能再设置Aess-Control-Allow-Origin为,必须用具体的域名 'Aess-Control-Allow-Credentials':true // 跨域请求携带身份信息(Credential,例如Cookie或者HTTP认证信息) }); ctx.send(null, '预检请求') } else { // 真实请求 await next() } } } export default cors
现在不管是简单请求还是非简单请求都可以跨域访问啦~
跨域时如何处理cookie
cookie
- 我们知道http时无状态的,所以在维持用户状态时,我们一般会使用cookie;
- cookie每次同源请求都会携带;跨域时cookie是不会进行携带发送的;
问题
- 由于cookie对于不同源是不能进行操作的;这就导致,服务器无法进行cookie设置,浏览器也没法携带给服务器(场景用户登录进行登录操作后,发现响应中有set-cookie,浏览器cookie并没有相应的cookie)
决解
- 浏览器请求设置withCredentials为true即可让该跨域请求携带 Cookie;使用axios配置axios.defaults.withCredentials = true
- 服务器设置Aess-Control-Allow-Credentials=true允许跨域请求携带 Cookie
以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对狼蚁SEO的支持。
编程语言
- 甘肃哪有关键词排名优化购买方式有哪些
- 甘肃SEO如何做网站优化
- 河南seo关键词优化怎么做电话营销
- 北京SEO优化如何做QQ群营销
- 来宾百度关键词排名:提升您网站曝光率的关键
- 卢龙关键词优化:提升您网站排名的策略与技巧
- 山东网站优化的注意事项有哪些
- 四川整站优化怎样提升在搜索引擎中的排名
- 疏附整站优化:提升网站性能与用户体验的全新
- 海南seo主要做什么工作售后服务要做到哪些
- 荣昌百度网站优化:提升您网站的搜索引擎排名
- 河北seo网站排名关键词优化如何做SEO
- 江西优化关键词排名推广售后保障一般有哪些
- 古浪SEO优化:提升你的网站可见性
- 西藏网站排名优化怎么把网站排名在百度首页
- 如何提升阳东百度快照排名:详尽指南