同源和跨域

运行方式

  1. 伪装一个网站(在本地)

    1.1 编辑 hosts 文件

    • mac: sudo vi /etc/hosts
    • windows: 用以管理员身份运行 git bash,vi C:/Windows/System32/drivers/etcetc/hosts

    1.2. 添加两行
    127.0.0.1 qq.com
    127.0.0.1 frank.com

    1.3. 保存关闭

  2. 监听 80 端口

    • Mac:sudo http-server -c-1 -p 80

    • Windows:

    1. 以管理员身份运行 git bash
    2. http-server -c-1 -p 80

浏览器的同源策略

同域名(或ip),同端口,同协议视为同一个域,一个域内的脚本仅仅具有本域内的权限,可以理解为本域脚本只能读写本域内的资源,而无法访问其它域的资源。这种安全限制称为同源策略。只有浏览器上才有同源政策。

举例来说,http://www.example.com/dir/page.html这个网址,协议是http://,域名是www.example.com,端口是80(默认端口可以省略)。它的同源情况如下。

  1. http://www.example.com/dir2/other.html:同源
  2. https://www.example.com/dir/other.html:不同源(协议不同)
  3. http://.example.com/dir/other.html:不同源(域名不同)
  4. http://www.example.com:81/dir/other.html:不同源(端口不同)

同源政策的目的,是为了保证用户信息的安全,防止恶意的网站窃取数据。

限制范围

  1. Cookie、LocalStorage 和 IndexDB 无法读取。
  2. DOM 无法获得。
  3. AJAX 请求不能发送。
    下面我将说一下针对浏览器下不同源的AJAX 请求不能发送所采取的两种跨域措施(实际上是发送了的,但是由于同源保护,无法读取到数据)

CORS跨域请求

CORS是跨源资源分享(Cross-Origin Resource Sharing)的缩写。它是W3C标准,是跨源AJAX请求的根本解决方法。相比JSONP只能发GET请求,CORS允许任何类型的请求。但是只有在ie8以上支持。
它的基本思想是:它允许浏览器向跨源服务器,发出XMLHttpRequest请求,从而克服了AJAX只能同源使用的限制。

1.简单模式 (GET、POST)
目标服务器在响应头里添加 Access-Control-Allow-Origin: http://xxx.com 即可,服务端仅允许来自 http://xxx.com 的访问

response.setHeader('Access-Control-Allow-Origin', 'http://frank.com')

2.复杂模式(除了GET、POST)
目标服务器在响应头里添加以下代码

response.setHeader('Access-Control-Allow-Origin', 'http://frank.com')
response.setHeader('Access-Control-Allow-Methods','POST,GET ,OPTIONS,PUT,PATCH,DELETE,HEAD')

会发两次请求,第一次是 OPTIONS 请求,询问目标服务器是否允许 PUT/PATCH等,如果允许,则发真正的请求。

JSONP跨域请求

JSONP是服务器与客户端跨源通信的常用方法。最大特点就是简单适用,老式浏览器全部支持。
它的基本思想是,网页通过添加一个 script 元素,向服务器请求JSON数据,这种做法不受同源政策限制;服务器收到请求后,将数据放在一个指定名字的回调函数里传回来。

原理:

1.首先是利用script标签的src属性来实现跨域。

2.通过将前端方法作为参数传递到服务器端,然后由服务器端注入参数之后再返回,实现服务器端向客户端通信。

3.由于使用script标签的src属性,因此只支持get方法
1.让目标网站在一个 xxx.js 里放置数据,形式是 JSON + Padding

{{callback}}({
"name":"frank",
"qb":10000
})

2.本网站使用 script 加载 xxx.js

var script = document.createElement('script');
script.src = 'http://qq.com/xxx.js';
script.onload = function () {
       console.log('加载xxx.js成功')
      console.log(window.frankUser)
}
document.head.appendChild(script);

3.约定用 callback=xxx 来交流
将2的代码改成如下:

function xxx(data){
    console.log('我得到的数据是')
    console.log(data)
}
var script = document.createElement('script')
script.src = 'http://qq.com/xxx.js?callback=xxx'
document.head.appendChild(script)

在nodejs上修改代码如下:

if(path === '/xxx.js'){
var callback = query.callback
var string = fs.readFileSync('./xxx.js', 'utf8')
response.setHeader('Content-Type', 'text/javascript;charset=utf-8')
setTimeout(function(){
response.end(string.replace('{{callback}}', callback))
}, Math.random() * 1000)
}

重点: 文件xxx.js加载到浏览器,就会调用xxx,json数据就会被当成参数传入xxx函数
4.将3的修改好的代码做封装

jsonp('http://qq.com/xxx.js',function(data){
    console.log('第一次')
    console.log(data)
})
jsonp('http://qq.com/xxx.js',function(data){
    console.log('第二次')
    console.log(data)
})
function jsonp(url,fn){
    var functionName='Frank'+parseInt(Math.random()*100000,10)
    window[functionName]=fn
    var script = document.createElement('script')
    script.src = url+'?callback='+functionName
    document.head.appendChild(script)
}
  1. jQuery 用法
$.ajax({
url:'http://qq.com/xxx.js',
dataType:'jsonp',
success:function(data){
console.log('第一次')
console.log(data)
}
})

JSONP 和 CROS 的区别

1.原理 上JSONP 是 script,CROS 是 JS 发出的请求
2.JSONP 只能 GET,CROS 都行
3.JSONP 不太安全,因为大家都可以访问(没有限制),CROS 有跨域限制

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

推荐阅读更多精彩内容