跨域

浏览器同源策略

浏览器出于安全考虑,默认情况下,只允许在本域接口下进行数据交互。这是浏览器的一种安全保护机制。主要限制有两个方面:

一、不同源的文档不能通过ajax实现请求,例如通过XHR实现Ajax通信,默认,XHR只能访问与包含它的页面位于同一个域中的资源,而不能访问其他域下的资源。

二、浏览器中不同域的框架也是不能通过js进行交互操作。

什么是跨域?

只要协议、域名、端口号中有任何一个不相同,就算是不同的域。要实现在不同域之间进行数据交互,就需要用到跨域的技术。

对于端口号和协议不同的情况,只能通过后台实现跨域。

跨域的几种方式:

1、CORS(跨域资源共享Cross-Origin Resource Sharing)

定义了在必须跨域访问的情况下,服务器和浏览器是如何进行沟通。cors背后的思想就是通过自定义的HTP头部的信息的反馈,决定整个请求响应过程的成败。

比较一下在使用cors实现跨域和没有跨域的情况下,ajax代码的区别:

var xhr=new XMLHttpRequest();

xhr.open('get','/loadMore?index='+pageIndex+'&length=5',true)  //  没有cors  url是一个相对路径

xhr.send();

var  xhr=new  XMLHttpRequest();

xhr.open('get', 'http://baidu.com:8080/getNews', true); // cors 实现跨域    URL换成其他域的绝对地址

xhr.send();

如上使用get方法发送一个请求时,在他的头部附加一个Origin头部,其中包含请求页面的源信息(协议、域名、端口)

Origin: http://baidu.com:8080

服务器根据这个头部信息来决定是否允许响应,如果服务器认为这个请求可以接受,就会在Access-Control-Allow-Origin的头部中回发同样的源信息

Access-Control-Allow-Origin: http://baidu.com:8080

如果没有这个头部,或者源信息不匹配,浏览器就会驳回请求。

2、JSONP

(JSON with padding)是JSON的一种使用格式,可以让网页访问其他网域下的资源,也叫填充式JSON

JSONP的特性:

html中的script标签可以引用其他域中的文件,可实现跨域访问。需要后端的支持与配合。

JSONP由两部分组成:回调函数和数据;   

回调函数就是在响应到来的时候,在页面中调用的函数,数据就是服务器发过来的json数据

callback({"name":"sty"})

使用jsonp来实现跨域:

js文件

var script=document.createElement('script');  //创建script元素

script.src='http://a.jrg.com:8080/getNews?callback=appendHtml';  //指定要访问的URL,其中回调函数是appendChild,用于处理数据

document.head.appendChild(script);  //在页面头部添加script节点

document.head.removeChild(script);  //在实现跨域功能后,移除script节点,保持页面的简洁

后端:

var cb = req.query.callback;

if(cb) {

     res.send(cb+'('+JSON.stringify(data)+')');

} else {

res.send(data);

}

JSONP的优缺点

JSONP的优点是:它不像XMLHttpRequest对象实现的Ajax请求那样受到同源策略的限制;它的兼容性更好,在更加古老的浏览器中都可以运行,不需要XMLHttpRequest或ActiveX的支持;并且在请求完毕后可以通过调用callback的方式回传结果。

JSONP的缺点则是:它只支持GET请求而不支持POST等其它类型的HTTP请求;它只支持跨域HTTP请求这种情况,不能解决不同域的两个页面之间如何进行JavaScript调用的问题。

CORS和JSONP对比

1、 JSONP只能实现GET请求,而CORS支持所有类型的HTTP请求。

2、 使用CORS,开发者可以使用普通的XMLHttpRequest发起请求和获得数据,比起JSONP有更好的错误处理。

3、 JSONP主要被老的浏览器支持,它们往往不支持CORS,而绝大多数现代浏览器都已经支持了CORS)

使用JSONP实现跨域,也会存在一定的安全隐患,例如XSS攻击

3、降域

浏览器中不同域的框架也是不能通过js进行交互的,但是不同框架之间可以获取到window对象,但却无法获取到相应的属性和方法。

例如  a.baidu.com 域下的一个 html 文档里有一个在其他域下(b.baidu.com)的 iframe 框架,在a.baidu.com 中并不能访问到 b.baidu.com 里的数据;

但可以获取到 b.baidu.com 中的 window 对象,但是这时 window 的属性和方法并不可用,两个文件中使用 document.domain('baidu.com')方法 把域名都降到baidu.com;

这样就可以在 a.baidu.com 中使用 iframe 里面的 window 的所有属性和方法了,通过window.frames[0] 获取到 iframe 框架,但是这时再通过window.frames[0].document.querySelector(element) 获取到 iframe 里的 element 元素。

在b.baidu.com 中通过window.parent.document.querySelector(element) 获取到html里的元素。

document.domain只适用于不同子域的框架之间实现跨域访问。

主要使用document.domain()


4、postMessage

这是HTML5的一种跨域访问资源的方法。

window.postMessage(message,targetOrigin)方法是html5新引进的特性,可以使用它来向其它的window对象发送消息,无论这个window对象是属于同源或不同源,目前IE8+、FireFox、Chrome、Opera等浏览器都已经支持window.postMessage方法。

document.querySelector('.main input').addEventListener('input',function() {

console.log(this.value);

window.frames[0].postMessage(this.value,"*")  //访问不同源的框架的message

})

window.addEventListener('message',function(e) {  /*在window上绑定一个监听事件,监测message*/

document.querySelector('.main input').value=e.data//通过e.data可以监听到别人发给我的信息

console.log(e.data);

})

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

推荐阅读更多精彩内容

  • 1. 什么是跨域? 跨域一词从字面意思看,就是跨域名嘛,但实际上跨域的范围绝对不止那么狭隘。具体概念如下:只要协议...
    w_zhuan阅读 503评论 0 0
  • 1. 什么是跨域? 跨域一词从字面意思看,就是跨域名嘛,但实际上跨域的范围绝对不止那么狭隘。具体概念如下:只要协议...
    他在发呆阅读 820评论 0 0
  • 跨域资源共享 CORS 对于web开发来讲,由于浏览器的同源策略,我们需要经常使用一些hack的方法去跨域获取资源...
    默默先生Alec阅读 575评论 0 0
  • 什么是跨域? 2.) 资源嵌入:、、、等dom标签,还有样式中background:url()、@font-fac...
    电影里的梦i阅读 2,348评论 0 5
  • 羌管翩逐花影,闹春风。倦人倚门叹镜心乱空。 花期负,朝与暮,盼君顾,自是君来不知奴归处。
    徐小丸子小姐阅读 323评论 6 3