JSONP_跨域

什么是同源策略

同源政策(same-origin policy)是指同域名(或ip),同端口,同协议视为同一个域,同域内的脚本只能读写本域内的资源,而无法访问其它域的资源,这种安全限制称为同源策略。当一个浏览器的两个tab页中分别打开来百度和谷歌的页面当浏览器的百度tab页执行一个脚本的时候会检查这个脚本是属于哪个页面的,即检查是否同源,只有和百度同源的脚本才会被执行。如果非同源,那么在请求数据时,浏览器会在控制台中报一个异常,提示拒绝访问。
同域指的是?
同协议:如都是http或者https
同域名:如都是http://baidu.com/ahttp://baidu.com/b
同端口:如都是8080端口
如果不是同源的,会受到三种限制:

1.Cookie、LocalStorage 和 IndexDB 无法读取。
2. DOM 无法获得。
3.AJAX 请求不能发送。

什么是跨域?跨域有几种实现形式

跨域
跨域是指从一个域名的网页去请求另一个域名的资源。比如从百度页面去请求谷歌的资源。跨域的严格一点的定义是:只要 协议,域名,端口有任何一个的不同,就被当作是跨域。
跨域有几种实现形式
一.JSONP
JSONP是服务器与客户端跨源通信的常用方法。最大特点就是简单适用,兼容性好。主要利用html中script标签可以引入其他域的js文件,利用这个特性可以实现跨域访问接口,需要后端的支持。实现步骤:
1.定义数据处理函数fun:
2.网页通过添加一个<script>元素,src的地址执行后端接口最后加个参数callback=fun,向服务器请求JSON数据,这种做法不受同源政策限制;
3.服务器收到请求后,将数据放在fun回调函数里传回来,输出fun(data):
4.fun(data)会放到script标签作为js执行,此时会调用fun(data),将data作为参数。
定义处理函数

  function foo(data){
      console.log(data.ip)
    }

网页动态插入<script>元素,由它向跨源网址发出请求。

function addScriptTag(src) {
  var script = document.createElement('script');
  script.src = src;
  document.head.appendChild(script);
  document.head.removeChild(script);
}
window.onload = function () { 
  addScriptTag('http://example.com/ip?callback=foo');
}

服务器收到这个请求以后,会将数据放在回调函数的参数位置返回

foo({
  "ip":"10.64.25.83"
})

由于<script>元素请求的脚本,直接作为代码运行。这时,只要浏览器定义了foo函数,该函数就会立即调用。作为参数的JSON数据被视为JavaScript对象,而不是字符串,因此避免了使用JSON.parse的步骤。
缺点:
1.只能通过GET方式请求,参数长度有限制,安全性比较差
2.需要后端的支持
二.CORS
CORS全称是"跨域资源共享"(Cross-origin resource sharing)。
它允许浏览器向跨源服务器,发出XMLHttpRequest请求。支持现代浏览器,IE10以上浏览器。CORS需要浏览器和服务器的支持,因此,实现CORS通信的关键是服务器。只要服务器实现了CORS接口,就可以跨源通信。
当CORS请求满足下面的条件时
1.请求方法是以下三种方法之一:
HEAD
GET
POST
2.HTTP的头信息不超出以下几种字段:
Accept
Accept-Language
Content-Language
Last-Event-ID
Content-Type:只限于三个值application/x-www-form-urlencoded、multipart/form-data、text/plain
基本思想是
1.当使用XMLHttpRequest()发送请求的时候,浏览器发现该请求不符合同源策略,会给该请求的头部信息添加一个origin字段,Origin字段用来说明,本次请求来自哪个源,服务器根据这个值,决定是否同意这次请求。
如果Origin指定的源,不被服务器允许,服务器也会返回正常的HTTP响应,浏览器发现响应头没有包含origin字段,就抛出错误,被onerror回调函数捕获,这种错误状态码无法识别。
2.如果指定的源,被服务器允许,服务器返回响应信息的响应头会包含origin的信息,如下:

Paste_Image.png

三.document.domain(也就是降域)
document.domain用于主域相同子域不同的场景
降域的设置也是有限制的,只能把document.domain,设置成自身或者更高一级的域,且主域必须相同,如:a.b.test.com中的某个文档的域可以设置成a.b.test.com、b.test.com、test.com。但是不可以设置成.com或者c.a.b.test.com或者baidu.com,因为baidu.com主域和当前域不同了。
使用方法
a页面中加入document.domain = ‘test.com’;
b页面中加入document.domain = ‘test.com’;
a.index.html

<div class="ct">
  <h1>使用降域实现跨域</h1>
  <div class="main">
    <input type="text" placeholder="http://a.test.com:8080/a.html">
  </div>
  <iframe src="http://b.test.com:8080/b.html" frameborder="0" ></iframe>
</div>
<script>
document.querySelector('.main input').addEventListener('input', function(){
  console.log(this.value);
  window.frames[0].document.querySelector('input').value = this.value;
})
document.domain = "test.com"

b.index.html

<div>
  <input id="input" type="text"  placeholder="http://b.test.com:8080/b.html">
</div>
<script>
   document.querySelector('#input').addEventListener('input', function(){
    window.parent.document.querySelector('input').value = this.value;
})
document.domain = 'test.com';
</script>
</html>

四,postMessage
postMessage是html5新增的方法,可以实现跨文本档、多窗口、跨域消息传递。该方法可以通过绑定window的message事件来监听发送跨文档消息传输内容。postMessage(data,origin)方法接受两个参数:
1.data:要传递的数据。
2.origin:字符串参数,指明目标窗口的源,协议+主机+端口号[+URL],URL会被忽略,所以可以不写,这个参数是为了安全考虑postMessage()方法只会将message传递给指定窗口,如果设置为"*",这样可以传递给任意窗口。
http://a.test.com/a.html

<div class="main">
        <input type="text" placeholder="http://a.test.com/a.html">
    </div>
    <iframe src="http://b.test.com/b.html" frameborder="0" ></iframe>
<script>
   $('.main input').addEventListener('input', function(){
               console.log(this.value);
               window.frames[0].postMessage(this.value,'*');
         })
 window.addEventListener('message',function(e) {
          $('.main input').value = e.data
                   console.log(e.data);
   });
   function $(id){
    return document.querySelector(id);
  }
</script>

http://a.test.com/a.html通过postMessage()方法向跨域的iframe页面http://b.test.com/b.html传递消息,b.html监听window的message事件就可以

<input id="input" type="text" placeholder="http://b.test.com/b.html">
<script>
$('#input').addEventListener('input', function(){
    window.parent.postMessage(this.value, '*');
})
window.addEventListener('message',function(e) {
        $('#input').value = e.data
    console.log(e.data);
});
function $(id){
    return document.querySelector(id);
}   
</script>

JSONP 的原理是什么

JSONP不是最新的数据格式,是json跨域获取的解决方案,通过jsonp获取的数据作为js的参数运行。浏览器有同源策略,会把跨域请求都禁止了,但是html的<script>标签,不受同源策略的影响,可以从其他源获取数据,所以我们可以通过script标签,引入其他源的数据,通过js代码进行解析。先定义处理函数functionname,然后通过添加一个<script>元素,src的地址是后端接口,在地址后加个请求参数callback=函数名,这个就是处理函数的函数名,向服务器请求JSON数据,服务器收到请求后,把数据放在回调函数中返回,返回的functionname(data)会放在script标签作为js执行,所以会调用functionname(data),将data作为函数的参数。

CORS是什么

CORS是跨源资源分享(Cross-Origin Resource Sharing)的缩写。它是W3C标准,是跨源AJAX请求的根本解决方法。相比JSONP只能发GET请求,CORS允许任何类型的请求。CORS需要浏览器和服务器同时支持,现代浏览器都支持此功能,IE浏览器要IE10以上。CORS的整个通信过程不需要用户参与,浏览器会自己完成,CORS与AJAX的同源通信一样,在发送AJAX请求的时候,浏览器会自动在头部添加一个origin字段,只要服务器允许cors的约定,就可以实现跨域通信。
CORS两种请求
cors有简单请求和非简单请求,只要满足
1)请求方法是HEAD/GET/POST三种方法之一;
2)HTTP的头信息不超出一下几种字段:Accept/Accept-Encoding/Accept-Language/Cache-Control/Connection/Cookie/Host/If-Modified-Since/Referer/User-Agent/Content-Type/Content-Language。其中Content-Type仅限于三个值:application/x-www-form-urlencoded、multipart/form-data、text/pain。就是简单请求,如果不满足就是非简单请求,
简单请求
对于简单请求,浏览器直接发cors请求,在头部添加origin字段,origin字段用来说明本次请求来自哪个源,服务器会根据这个origin,决定是否同意通信,如果服务器不同意,也会返回正常的http响应,浏览器没发现有origin这个字段,就是报错,表示不能跨域通信。
** 非简单请求**
非简单请求是对服务器有特殊要求的请求,比如请求方法是PUT/DELETE,或者Content-Type字段的类型是application/json。
非简单请求的CORS请求,会在正式itongxin之前,增加爱一次HTTP查询请求,叫预检请求(preflight)。
  浏览器现询问服务器,当前网页所在的域名是否在服务器的许可名单中,以及可以使用哪些HTTP动词和头信息字段。只有得到肯定答复,浏览器才会发出正式的XMLHttpRequest请求,否则就报错。
除了Origin字段,预检请求的头信息还包括两个特殊字段:
  (1). Access-Control-Request-Method
  该字段是必须的,用来列出浏览器的CORS请求会用到哪些HTTP方法,例子中是POST。
  (2). Access-Control-Request-Headers
  该字段是都好分割的字符串,指定浏览器CORS请求会额外发送的头信息字段,上面的例子默认application/json对应的额外字段是”Content-Type”。
服务器收到预检请求后,检查Origin、Access-Control-Request-Method和Access-Control-Request-Headers字段以后,确认允许跨源请求,并做出回应。
如果服务器否定了预检请求,会返回一个正常的HTTP Response,但是没有任何CORS相关的头信息字段。这时候浏览器认为i额服务器不同意预检请求,因此出发一个错误,被XMLHttpRequest对象的onerror毁掉函数捕获。控制台会打印出如下报错信息。
一旦服务器通过了预检请求,以后每次浏览器正常的CORS请求就都与简单请求一样,包括Origin字段信息。服务器的回应也会有Access-Control-Allow-Origin字段

根据视频里的讲解演示三种以上跨域的解决方式 ,写成博客

博客地址

最后一个cors的介绍参考了阮一峰老师的日志。

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

推荐阅读更多精彩内容

  • 1.什么是同源策略浏览器出于安全方面的考虑,只允许与本域下的接口交互。不同源的客户端脚本在没有明确授权的情况下,不...
    24_Magic阅读 488评论 0 0
  • 1- 同源策略: 首先理解什么叫同源同源指的是协议、域名、端口都必须一致。只要其中一个不一致都不是同源。 浏览器中...
    osborne阅读 174评论 0 1
  • 1: 什么是同源策略 最初,它的含义是指,A网页设置的 Cookie,B网页不能打开,除非这两个网页"同源",所谓...
    好奇而已阅读 293评论 0 0
  • 题目1: 什么是同源策略 同源策略(Same Origin Policy): 浏览器出于安全方面的考虑, 只允许与...
    cctosuper阅读 228评论 0 1
  • 中老年势力这几年可谓异军突出,说到中老年势力,你脑子里闪过的还只是长辈群里形形色色的早安晚安表情包跟“网络一线牵,...
    T立方云工作平台阅读 383评论 0 1