跨域及其解决方案

同源策略

引用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请求。
核心思想:网页通过添加一个 // 向服务器test.com发出请求,该请求的查询字符串有一个callback参数,用来指定回调函数的名字 // 处理服务器返回回调函数的数据

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就可以解决这一情况


然后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

你可能感兴趣的:(跨域及其解决方案)