什么是跨域?

为什么会产生跨域问题?

        因为浏览器为了请求安全而引入的基于同源策略的安全特性。

        当页面和请求的协议、主机名或端口不同时,浏览器判定两者不同源,即为跨域请求。需要注意的是跨域是浏览器的限制,服务端并不受此影响。

 如上图所示,一个 origin 由协议(Protocol)、主机名(Host)和端口(Port)组成,这三块也是同源策略的判定条件,只有当协议、主机名和端口都相同时,浏览器才判定两者是同源关系,否则即为跨域。

前端常见的跨域解决方案有 JSONP 、CORS、反向代理(Reverse Proxy)等。

1.jsonp:利用html里面的script标签,可以加载一些其他域下的数据

        在设计这个script标签的时候就允许在别的源请求脚本,所以就有开发人员利用这个漏洞来进行跨域,就是jsonp

<script >
function getJsonp(res){
   console.log(res) 
}
</script>
<script src="文件路径?callback=getJsonp" type="text/javascript"></script>

        h5的script标签默认text/javascript,正是因为定义了这个类型,请求的内容会被浏览器当作js执行了

        jq的ajax 可以直接设置datatype:‘jsonp’,jsonpCallback:“callback”;

        html标签<link><script><img><iframe>等都是具有跨域特性的,可以直接访问别的源资源

2.CORS后端配合解决

        CORS:跨域资源共享 支持所有的主流浏览器,ie9+也支持

        XMLHttpRequest发送请求的时候,如果不同源,需要在 headers{ Origin }属性,是w3c标准,属于跨域ajax请求的根本解决方法

        1.普通跨域请求:只需后端(服务器端)设置Access-control-allow-origin,*所有域名端口都可以访问

        2.带cookie跨域请求:前后端都需要进行cookie设置

        前端设置 根据xhr.withCredentials字段判断是否携带带有cookie

vue本地开发使用的,服务器代理跨域 proxy 本质上也是cors跨域

        vue的项目可以设置代理(生产环境无效。解决:.env文件)

        通过中间件来实现,浏览器有跨域限制,但是服务器没有跨域限制,所有中间件其实就是服务器(服务器对数据进行了转发而已)

//代理跨域 proxy 本质上也是cors跨域
//vue.config.js
devServer:{
   proxy:{
        '/api':{
            target:'http://www.baidu.com',//设置你调用的接口域名和端号
            changeOrigin:true,//跨域
            pathRewrite: {
                 "^/api":'/',//识别api开头的地址,替换/api为/           
            }
    } 
}

3.Nginx反向代理

        Nginx实现原理类似于Node中间件代理,需要搭建一个中转的nginx服务器,用于转发请求。

        使用nginx反向代理实现跨域,是最简单的跨域方式,只需要修改nginx的配置即可以解决跨域问题,支持所有的浏览器,支持session,不需要修改任何代码,并不会影响服务器性能。

        我们只需要配置nginx,在一个服务器配饰多个前缀转发http/https请求到多个真实的服务器即可。这样,这个服务器上多有url都是相同的域名,协议和端口。因此,对于浏览器来说,这些url都是同源的,没有跨域限制。而实际上,这些url实际是有屋里服务器提供服务的。这些服务器内的javascript可以跨域调用所有这些服务器上的url

#proxy
server{
    #nginx监听所有www.a.com:80端口收到的请求
    listen           80;
    server_name      www.a.com;
    location / {
        proxy_pass    http://www.b.com; #反向代理,后端程序会接受到"http://www.b.com"请求
        proxy_cookie_domain  www.b.com www.a.com;
        index    index.html index.html; 
        
        add_header   Access-Control-Allow-Origin http://www.a.com;
        add_header   Access-Control-Allow-Credentials true;       
    }
}

4.H5 window.postMessage跨域 主流浏览器支持 ie需要8+以上 

postMessage可以解决

        页面和其他打开的新窗口数据传递

        多窗口之间消息传递

        页面与嵌套的iframe消息传递

        上面三个场景的跨域数据传递

//父窗口向子窗口发送消息(第一个参数代表发送内容,第二个参数代表接收消息窗口url)
window.postMessage("字符串","*")
//子窗口调用message事件,监听父窗口发送的消息
window.addEventListener('message',function(res)=>{
   console.log(res.data);//发送内容 
},false)

5.websocket

        websocket 是html5的一个持久化的协议,它实现了浏览器与服务器的全双工通信,同时也是一种跨域的一种解约方案。

        websocket和http都是应用层协议,都基于TCP协议。但是webSocket是一种双向通信协议,在建立链接之后,websocket的服务器与客户端能主动向对方发送或接收数据。同时,websocket在建立连接时需要借助http协议,链接建立好了之后client与server之间的双向通信就与http无关了。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值