什么是同源策略
同源策略是一种约定,浏览器最核心的也最基本的安全功能,缺少同源策略,浏览器很容易受到XSS、CSFR等攻击。所谓同源就是协议
、域名
、端口
都相同。
同源策略限制以下几种行为:
- 1、Cookie、localStorage 和 IndexDB 无法读取
- 2、DOM 和 JS 对象无法获得
- 3、AJAX 请求不能发送
JSONP跨域
只要说到跨域,就必须聊到JSONP,JSONP全程是:JSON with Padding,在实际开发中我们为了减轻web服务器的负载,我们把js、css和img等静态资源分离到另一台独立域名的服务器上或者cdn中,在html页面在通过相应的标签从不同域名下加载资源,浏览器是允许的。因此我们知道
web页面调用js文件不受浏览器的同源策略的影响,所以通过script标签可以进行跨域的请求
实现过程
- 动态创建一个script标签
- script标签的src属性设置接口地址
- 接口参数,必须要带一个自定义函数名,要不然后台无法返回数据
- 通过定义函数名去接受返回的数据
<script>
var script = document.createElement('script');
script.type = 'text/javascript';
// 传参一个回调函数名给后端,方便后端返回时执行这个在前端定义的回调函数
script.src = 'http://www.domain2.com:8080/login?user=admin&callback=handleCallback';
document.head.appendChild(script);
// 回调执行函数
function handleCallback(res) {
alert(JSON.stringify(res));
}
</script>
JSONP缺点:只支持GET请求而不支持POST等其他类型的HTTP请求。
CORS跨域
CORS是一个W3C标准,全称是“跨域资源共享”,它允许浏览器向资源服务器发出 XMLHttpRequest 请求,从而克服ajax只能同源使用的限制。只需要设置服务器Access-Control-Allow-Origin响应头
浏览器将CORS请求分为两类:简单请求和非简单请求
简单请求
主要满足两种条件就是简单请求:
- 1、请求方式是GET、POST、HEAD
- 2、Content-Type:只限于三个值application/x-www-form-urlencoded、multipart/form-data、text/plain
简单请求会自动在头信息之中,增加一个origin字段,origin字段用来说明,本次请求来自那个源(协议 + 域名 + 端口)。服务器根据个值,决定是否同意这次请求。
非简单请求
非简单请求是对服务器有特俗要求的请求,比如请求的方式是put 或 delete, 或者Content-Type 字段的类型是application/json。
非简单请求的CORS请求,会在正式通信之前,增加一次http查询请求,称为“预检”请求。以获知服务器是否允许该实际请求,"预检请求“的使用,可以避免跨域请求对服务器的用户数据产生未预期的影响和服务器的压力。
浏览器先询问服务器,当前网页所在的域名是否在服务器的许可名单之中,以及可以使用哪些http动词和头信息字段。只有得到肯定的答复,浏览器才会发出正式的XMLHttpRequest 请求,否则就报错。
预检请求用的请求方式是options, 表示这个请求是用来询问的。预检测请求的流程,如果是一个跨域请求,浏览器会自动给请求带上origin头部,表明当前的来源域;服务器判断这个请求是否允许跨域,就会在返回时,选择是否带上Access-Control-Allow-Origin 头部,最后浏览器判断 Access-Control-Allow-Origin 就知道,后续请求是否发送。
代理接口跨域
同源策略只是浏览器的安全策略,不是http协议的一部分,服务器调用http接口只是使用http协议,不会执行js脚本,不需要同源策略,也就不存在跨域问题
#proxy服务器
server {
listen 80;
server_name www.domain1.com;
location / {
proxy_pass http://www.domain2.com:8080; #反向代理
index index.html index.htm;
}
}
在现在vue/react主流框架中,都是基于node + webpack + webpack-dev-server 代理接口跨域。在开发环境下,webpack-dev-server主要是启动了一个使用express服务器,通过配置代理,前端请求的接口通过服务器转发请求到原接口,实现跨域请求。
document.domain + iframe跨域
此方案仅限一级域名(主域名)相同,子域不同的跨域应用场景。实现原理:两个页面都通过js强制设置document.domain为基础主域,就实现了同域
1.)父窗口:(www.domain.com/a.html)
<iframe id="iframe" src="http://child.domain.com/b.html"></iframe>
<script>
document.domain = 'domain.com';
var user = 'admin';
</script>
2.)子窗口:(child.domain.com/b.html)
<script>
document.domain = 'domain.com';
// 获取父窗口中变量
alert('get js data from parent ---> ' + window.parent.user);
</script>
扩展 Content-Type
- 1、application/x-www-form-urlencoded: 提交的数据按照 key1=val1&key2=val2 的方式进行编码
- 2、application/json:提交的数据以JSON 字符串形式进行编码
- 3、multipart/form-data: 表单文件上传
- 3、text/xml: 数据-微信api
常见问题FAQ
- 免费下载或者VIP会员专享资源能否直接商用?
- 本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
- 提示下载完但解压或打开不了?
- 找不到素材资源介绍文章里的示例图片?
- 模板不会安装或需要功能定制以及二次开发?
发表评论
还没有评论,快来抢沙发吧!