关于前端跨域处理的方法总结

前端跨域的那些总结

做项目期间一直有遇到关于跨域方面的问题,之前由于没有上过生产环境,对于这方面的问题还不够全面,只是在前后端分离的方面遇到过,还是本地环境,主要是基于JSONP解决的;在最近的Vue项目中遇到的本地开发环境的跨域解决临时使用了dev中的index.js配置文件下内置的proxyTable属性配置解决跨域,测试环境行的通,但是生产环境则不行,会踩到这,还是对跨域不够清楚,最后重新复习了关于跨域方面的知识,对于线上环境配置了nginx反向代理后解决了跨域问题;下面,总结下对于跨域的认识。

  • 为什么会有跨域问题的出现?

在我们的浏览器中有一条策略叫做“同源策略”,什么叫同源策略呢?也就是当我们前后端数据交互的时候,如果两个页面所处的端口或者子域名以及通信协议中的任何一个不同,那么当你需要在违反同源策略的情况下在两个页面间通信时,就会出现跨域错误,因为浏览器出于安全考虑,限制了此类访问操作;但是日常开发操作中对于跨域操作的使用非常频繁,所以如何解决此类限制,完成不同页面间的数据通信,就是我们学习跨域操作及其工作原理的原因。

  • 前端有哪些处理方式可以解决跨域问题?
    1、document.domain

    1.场景:浏览器的同源策略有一些限制,首先,不能用ajax方法去请求不同源的资源;并且,浏览器中不同域的框架之间是不能进行数据通信的,假如从‘https://www.baidu.com/request.html’中请求‘https://baidu.com/response.html’中的数据,在两个不同的源中有一个iframe,但是由于是不同域,我们就没法通过JS来访问iframe中的数据和方法。
    解决办法:我们可以将两个不同源文件中的document.domain设成相同的域名,但这里,需要提醒的一点是,我们在设置document.domain时候,只能将其设置成自身或更高一级的父域,并且二者的主域必须相同。

 ``` javascript
    <iframe src="https://www.baidu.com/request.html">
    <script>
         document.domain = " baidu.com " //这里是将A中的document.domain设置成主域
     </script>
  
<iframe src="https://baidu.com/response.html">
<script>
    document.domain = "baidu.com" //B页面的document.domain设置相同的domain即可
</script>

 // 但是,此类解决办法只适用于不同子域的框架间的交互。
  ```

2、location.hash

场景:对于页面中有iframe的页面中,父窗口可以对iframe的url进行读写。而在URL上有一部分#加上后面的字符可以用来进行锚点定位,这部分就是这里会提到的hash。利用修改URL的hash部分可以进行双向通信,从而达到跨域的目的,每个window通过改变其他window的location来发送消息,其他窗口通过监听URL的变化来接受消息,这个方式的通信会造成一些不必要的浏览器历史记录,而且有些浏览器不支持onhashchange事件,需要通过轮询操作来获取URL的改变,最后,这样做也存在一定问题,就是不仅数据会直接暴露在url中,数据容量和类型都有限。

示例:假如当前父页面' baidu.com/request.html ',其中嵌入的页面是’ xupt.edu.cn/response.html ‘,要实现此两个页面间的通信可以通过以下方法。

> 1.request.html传送数据到 response.html , request.html下修改为iframe的src为 'xupt.edu.cn/response.html'

>2.response.html监听到相应数据发生变化,触发对应操作。

>3.response.html传送数据到 request.html 中,但是由于两个页面不在同源下,会受到限制,所以要借助父窗口域名下的一个代理iframe。

>4.request.html下创建一个隐藏的iframe, 此Iframe的src是baidu.com域下的,并挂上要传送的hash数据;如 src = "baidu.com/proxy.html"

>5.proxy.html监听到URL变化,修改a.html变化的URL,由于二者是同源,所以在proxy.html中可修改a.html的url hash

>6.request.html监听到url变化,触发相应操作。
    // request.html 简单处理代码
    try{
        parent.location.hash = 'data';
    }catch(e){
        // ie Chrome存在安全机制,所以无法修改 parent.location.hash
        var _proxy = document.createElement('iframe');
        
        _proxy.style.display = 'none';
        _proxy.src = 'baidu.com/proxy.html';
    }
    
    // proxy.html关键代码处理
    // 由于proxy.html和baidu.com/request.html存在与同域,所以可以正常改变其location.hash的值。
    
    parent.parent.location.hash = self.location.hash.substring(1);

3、Html5的 postMessage( )
场景:该属性各大主流浏览器均支持,主要是包括接收信息的方法和发送信息的postMessage方法,比如A页面通过内嵌Iframe,获取一个B页面,就可以通过此方法实现A页面和B页面的通信。

    // A页面通过 postMessage() 发送消息
    window.onload = function (){
        var _iframe = document.getElementById('ifr');  
        var targetOrigin = "https://www.google.com";  
        _iframe.contentWindow.postMessage('hello world!', targetOrigin);
    }
    
    // 在B页面通过监听 message 事件并接收消息
    var onmessage = function (event){
      var data = event.data;//消息  
      var origin = event.origin;//消息来源地址  
      var source = event.source;//源Window对象  
      if(origin=="https://www.baidu.com"){  
        console.log(data);//hello world!  
      }  
    };
    
    if (typeof window.addEventListener != 'undefined') {  
      window.addEventListener('message', onmessage, false);  
    } else if (typeof window.attachEvent != 'undefined') {  
      //IE浏览器需要做特殊处理
      window.attachEvent('onmessage', onmessage);  
    }  

5、通过JSONP跨域
场景:通过script标签引入的JS不回受到浏览器同源策略的限制,所以我们可以通过生成的script标签引入一个JS或者其他后缀形式的文件,但是这些文件返回的是一个JS函数的调用。
> 如果作为一个JS文件引入,那么接口或请求地址返回的必须是一个可以执行的JS文件,这里需要在编写的时候和后端约定好规范。

  • 虽然此方法兼容性好,不用XMLHttpRequest或ActiveX的支持;并且在请求完毕后可以通过调用callback的方式回传结果;但是只支持GET请求,不能解决不用域的两个页面之间如何进行Javascript调用的问题。

6、通过CROS跨域
场景:CROS全称是跨域资源共享,定义了必须在访问跨域资源时浏览器与服务器应该如何沟通,CROS背后的基本思想就是使用自定义的HTTP头部让浏览器与服务器进行数据通信,主流浏览器均支持该功能,但是IE浏览器版本不能低于IE10。并且,使用此方法的关键在于服务器的配置处理,只要服务器实现了CORS接口,就可以实现跨域通信。

在服务端里面,对于CROS的支持,主要是通过设置响应头Access-Control-Allow-Origin来进行,如果浏览器监测到相应的设置,就可以允许跨域通信请求。
上边提到的JSONP实现跨域,有很大的局限性,只支持GET请求,但是在CROS实现的跨域请求访问中,支持所有的数据请求方式,并且有更好的错误处理方式,能够接收简单的XMLHttpRequest发起的请求。

7、设置Window.name属性
场景: 每个window对象有个name属性,该属性有个特征:在一个创口的生命周期之内,窗口载入的所有页面都是共享一个window.name的,每个页面对window.name都有读写的权限,window.name是持久存在一个窗口载入过的所有页面中的,并不会因为新页面的载入而进行重置;并且,由于安全原因限制,浏览器始终都会保持window,name是 string 类型。

这种方法与document.domain相比,放宽了域名后缀要相同的限制,可以从任意页面获取string类型的数据。

8、配置反向代理服务器
场景:基本解决思路就是将其服务所在的服务器配置成所需的跨域资源访问的反向代理服务器,在nginx服务器配置上,将当前接收到需要发送的各类请求链接,按照实际需要,配置好转发规则,通过服务器处理相应的请求链接,对于浏览器来说,这些请求是发送到本机服务器的,是同源的,而实际请求是又服务器进行转发,这样就不会触及浏览器的同源策略限制,就能实现正常的跨域通信请求等操作。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 162,306评论 4 370
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 68,657评论 2 307
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 111,928评论 0 254
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,688评论 0 220
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 53,105评论 3 295
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 41,024评论 1 225
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 32,159评论 2 318
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,937评论 0 212
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,689评论 1 250
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,851评论 2 254
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,325评论 1 265
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,651评论 3 263
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,364评论 3 244
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,192评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,985评论 0 201
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 36,154评论 2 285
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,955评论 2 279

推荐阅读更多精彩内容

  • 跨域资源共享 CORS 对于web开发来讲,由于浏览器的同源策略,我们需要经常使用一些hack的方法去跨域获取资源...
    默默先生Alec阅读 547评论 0 0
  • 什么是跨域? 2.) 资源嵌入:、、、等dom标签,还有样式中background:url()、@font-fac...
    电影里的梦i阅读 2,320评论 0 5
  • 我在水中弹琴 枫叶从身边飘落 四周是一片静谧 只有我的琴音 和着水声泠泠 一片安宁 这片安宁啊 连月儿都被吸引 映...
    谢子章阅读 174评论 1 1
  • 原来当你开始干事情的时候,一切会变得繁杂而有意义。 连自己都把握不住自己的人如何让别人去信任你。...
    神赐Doreen阅读 156评论 0 0
  • 我想,对父辈的理解,对选择的坚守,这是对昨天的尊重,也是对明天的负责。 刚立春,老天爷应该是也眷恋这早春的时光,开...
    骡子看电影阅读 248评论 0 0