同源策略
引用MDN上的同源策略:是一个重要的安全策略,它用于限制一个origin的文档或者它加载的脚本如何能与另一个源的资源进行交互。它能帮助阻隔恶意文档,减少可能被攻击的媒介。
什么是同源呢?
同源:指两个页面具有相同的协议,域名,端口号
同源策略到底限制了哪些行为?
1、cookie,localstorage和IndexDB无法读取
2、DOM无法获取
3、Ajax请求不能发送
什么是跨域 ?
协议,域名(主机号),端口号有一个不同就是跨域
当前页面url | 被请求页面url | 是否跨域 | 原因 |
---|---|---|---|
http://www.test.com/ | http://www.test.com/index.html | 否 | 协议、域名、端口号相同 |
http://www.test.com/ | https://www.test.com/index.html | 跨域 | 协议不同 |
http://www.test.com/ | http://www.baidu.com/ | 跨域 | 域名不同 |
http://www.test.com:8080/ | http://www.test.com:6001/ | 跨域 | 端口号不同 |
如何解决跨域?
1.JSONP
JSONP 是服务器与客户端跨源通信的常用方法。最大特点就是简单适用,兼容性好(兼容低版本IE),缺点是只支持get请求,不支持post请求。
核心思想:网页通过添加一个<script>元素,向服务器请求 JSON 数据,服务器收到请求后,将数据放在一个指定名字的回调函数的参数位置传回来。
<script src="http://test.com/data.php?callback=dosomething"></script>
// 向服务器test.com发出请求,该请求的查询字符串有一个callback参数,用来指定回调函数的名字
// 处理服务器返回回调函数的数据
<script type="text/javascript">
function dosomething(res){
// 处理获得的数据
console.log(res.data)
}
</script>
2.CORS
CORS是W3C标准,允许浏览器向跨源服务器发送XMLHttpRequest请求,从而克服了AJAX只能同源使用的限制,并且需要浏览器和服务器同时支持,目前所有的浏览器都支持该功能除了IE,IE浏览器不能低于IE10,是 JSONP 模式的现代版。与 JSONP 不同,CORS 除了 GET 要求方法以外也支持其他的 HTTP 要求
此方法需要后端配合(配置)
MDN:https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Access_control_CORS
3.跨窗口操作DOM之postMessage
window.postMessage(data,origin) 是HTML5的一个接口,专注实现不同窗口不同页面的跨域通讯,它可用于解决以下方面的问题:
a.) 页面和其打开的新窗口的数据传递
b.) 多窗口之间消息传递
c.) 页面与嵌套的iframe消息传递
例如:a.html不能操作iframe(b.html)里面的dom,那么使用postMessage就可以解决这一情况
<html>
<div>
<button @click="postMessage">给iframe发消息</button>
<iframe id="myIframe" src="b.html"></iframe>
</div>
<script>
var myIframe = document.getElementById('myIframe');
myIframe.contentWindow.postMessage('hello world!', 'b.html');
</script>
</html>
然后b.html页面通过message事件监听并接受消息:
window.addEventListener('message',function(event) {
var data = event.data; //消息
var origin = event.origin; //消息来源地址
var source = event.source; //消息来源的Window对象
// 为了安全性,一定要对来源做校验
if (origin == "a.html") {
alert(data); //hello world!
source.postMessage('回信啦', 'a.html'); // a.html页面也用message方法接收就行
}
});
4. nginx反向代理接口跨域
此方法需要将前端代码放在nginx的静态资源服务器上,
#proxy服务器
server {
listen 81;
server_name www.domain1.com;
location / {
proxy_pass http://www.domain2.com:8080; #反向代理
proxy_cookie_domain www.domain2.com www.domain1.com; #修改cookie里域名
index index.html index.htm;
# 当用webpack-dev-server等中间件代理接口访问nignx时,此时无浏览器参与,故没有同源限制,下面的跨域配置可不启用
add_header Access-Control-Allow-Origin http://www.domain1.com; #当前端只跨域不带cookie时,可为*
add_header Access-Control-Allow-Credentials true;
}
}
如果使用vue开发且是在开发环境下可以使用node代理:
以vuecli举例
在vue.config.js中配置
module.exports = {
devServer: {
proxy: {
'/dy': { // 别名
target: 'https://www.iesdouyin.com/web/api/v2', // 目标地址
ws: true,
changeOrigin: true, //开启跨域
pathRewrite: {
'^/dy': '' //路径重命名
}
}
参考文章
https://blog.csdn.net/yup1212/article/details/87633272
https://developer.mozilla.org/zh-CN/docs/Web/Security/Same-origin_policy
https://www.jianshu.com/p/9f0ffb551309