浏览器跨域

跨域的发生

浏览器跨域的问题来源于同源策略

说明举例是否允许通信
同一域名,不同文件或路径http://www.domain.com/a.js http://www.domain.com/b.js支持
同一域名,不同端口http://www.domain.com:8000/ http://www.domain.com不支持
同一域名,不同协议http://www.domain.com https://www.domain.com不支持
域名和域名对应相同iphttp://www.domain.com http://192.168.2.1不支持
主域相同,子域不同http://www.domain.com http://domain.com不支持
不同域名http://www.b.com http://www.a.com不支持

怎么解决跨域

跨域的解决办法有很多种
来自掘金社区
这里推荐两种:nginx反向代理、cors(跨域资源共享)

websocket协议

websocket协议是一种全双工通信协议,并且该协议被允许跨域请求。

window.postMessage

window对象可以获取其他窗口的一个引用,比如iframe的contentWindow属性、执行window.open返回的窗口对象、或者是命名过或数值索引的window.frames。

<body>
    <button onclick="go()">go</button>
    <button onclick="send()">send</button>
</body>
<script>
    // postmessage  使用8081端口打开
    var a
    function go() {
        a = window.open("http://192.168.1.6:8080/p2.html")
        send()
    }
    function send(){
        a.postMessage(2,"http://192.168.1.6:8080/p2.html")
    }
    window.addEventListener("message",function(event){
        console.log(event.data)   // 3
    },false)
</script>
<script>
    // p2   使用8080端口
    var targetWindow = window.opener
    window.addEventListener("message",function(event){
        console.log(event.data,"收到")  //2 
        targetWindow.postMessage(event.data + 1,event.origin)
    },false)
</script>

此时可以使用postMessage方法向其它页面传递消息

document.domain + iframe

当主域相同子域不同时可以使用这个方式,两个域都通过js强制设置document.domain为基础主域,就实现了两页面之间相互访问变量

window.location.hash + iframe

在这个实现方式中,a,c是同域,b是另一个域,整体实现方式是 a →b →c→a,a到b到c之间的通讯可以依赖hash值的变化,iframe页面监听hash值变化来获取值,c到a因为是同域可以使用window.parent.parent实现c访问a的回调方法

window.name + iframe

这个方案主要是利用window.name的特性,name的值在不同页面,不同域加载后依然存在,并且可以支持2M的值(iE、firefox支持32M,听说啊)。利用iframe加载一个跨域文件,加载完成后设置window.name之后再重定向到一个同域的页面,同域的页面即可通信获得window.name携带的参数

nginx代理

因为同源策略限制的是浏览器的请求,所以在服务器端即使跨域也没有影响,利用服务器访问对应的资源统一通过代理返回即可解决跨域
这个方式是利用nginx反向代理的能力,将不同域之间的请求归并到一个域下,首先需要安装nginx,然后配置两个域的代理,都使用同一端口 ,但是路径不同。比如:3000/a指向实际业务的1000端口,:3000/b指向实际业务的4000的端口

cors跨域资源共享

服务端设置Access-Control-Allow-Origin,允许资源被跨域访问。这种方式对于不携带cookie的请求是很方便的,但是如果需要携带cookie可以参考nginx代理

node代理

利用node服务做代理实现跨域请求

JsonP解决跨域

这种方式是利用浏览器在请求js,css,img等静态资源时是被浏览器允许访问跨域资源的(因为可能需要静态资源部署在资源服务器),基于此原理,可以在需要请求的时候使用js添加script标签,并设置回调函数。在服务端返回对应script标签的资源时将参数携带在回调函数中

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

后端返回

handleCallback({"status": true, "user": "admin"})

跨域时请求

简单请求不会触发预检请求Options Preflight request
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

霜叶w

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值