JavaScript的10种跨域共享的方法

在客户端编程语言中,如javascript和ActionScript,同源策略是一个很重要的安全理念,它在保证数据的安全性方面有着重要的意义。同源策略规定跨域之间的脚本是隔离的,一个域的脚本不能访问和操作另外一个域的绝大部分属性和方法。那么什么叫相同域,什么叫不同的域呢?

同源策略

在客户端编程语言中,如javascript和 ActionScript,同源策略是一个很重要的安全理念,它在保证数据的安全性方面有着重要的意义。同源策略规定跨域之间的脚本是隔离的,一个域的脚本不能访问和操作另外一个域的绝大部分属性和方法。那么什么叫相同域,什么叫不同的域呢?当两个域具有相同的协议(如http), 相同的端口(如80),相同的host(如www.example.org),那么我们就可以认为它们是相同的域。比如 http://www.example.org/index.html和http://www.example.org/sub/index.html是同域,而http://www.example.org, https://www.example.org, http://www.example.org:8080, http://sub.example.org中的任何两个都将构成跨域。同源策略还应该对一些特殊情况做处理,比如限制file协议下脚本的访问权限。本地的HTML文件在浏览器中是通过file协议打开的,如果脚本能通过file协议访问到硬盘上其它任意文件,就会出现安全隐患,目前IE8还有这样的隐患。

受到同源策略的影响,跨域资源共享就会受到制约。但是随着人们的实践和浏览器的进步,目前在跨域请求的技巧上,有很多宝贵经验的沉淀和积累。这里我把跨域资源共享分成两种,一种是单向的数据请求,还有一种是双向的消息通信。接下来我将罗列出常见的一些跨域方式,以下跨域实例的源代码可以从这里获得。

单向跨域

JSONP

JSONP (JSON with Padding)是一个简单高效的跨域方式,HTML中的script标签可以加载并执行其他域的javascript,于是我们可以通过script标记来动态加载其他域的资源。例如我要从域A的页面pageA加载域B的数据,那么在域B的页面pageB中我以JavaScript的形式声明pageA需要的数据,然后在 pageA中用script标签把pageB加载进来,那么pageB中的脚本就会得以执行。JSONP在此基础上加入了回调函数,pageB加载完之后会执行pageA中定义的函数,所需要的数据会以参数的形式传递给该函数。JSONP易于实现,但是也会存在一些安全隐患,如果第三方的脚本随意地执行,那么它就可以篡改页面内容,截获敏感数据。但是在受信任的双方传递数据,JSONP是非常合适的选择。

flash URLLoader

flash有自己的一套安全策略,服务器可以通过crossdomain.xml文件来声明能被哪些域的SWF文件访问,SWF也可以通过API来确定自身能被哪些域的SWF加载。当跨域访问资源时,例如从域www.a.com请求域www.b.com上的数据,我们可以借助flash来发送HTTP请求。首先,修改域www.b.com上的crossdomain.xml(一般存放在根目录,如果没有需要手动创建) ,把www.a.com加入到白名单。其次,通过Flash URLLoader发送HTTP请求,最后,通过Flash API把响应结果传递给JavaScript。Flash URLLoader是一种很普遍的跨域解决方案,不过需要支持iOS的话,这个方案就无能为力了。

Access Control

Access Control是比较超越的跨域方式,目前只在很少的浏览器中得以支持,这些浏览器可以发送一个跨域的HTTP请求(Firefox, Google Chrome等通过XMLHTTPRequest实现,IE8下通过XDomainRequest实现),请求的响应必须包含一个Access- Control-Allow-Origin的HTTP响应头,该响应头声明了请求域的可访问权限。例如www.a.com对www.b.com下的 asset.php发送了一个跨域的HTTP请求,那么asset.php必须加入如下的响应头:

header("Access-Control-Allow-Origin: http://www.a.com");

window.name

window 对象的name属性是一个很特别的属性,当该window的location变化,然后重新加载,它的name属性可以依然保持不变。那么我们可以在页面 A中用iframe加载其他域的页面B,而页面B中用JavaScript把需要传递的数据赋值给window.name,iframe加载完成之后,页面A修改iframe的地址,将其变成同域的一个地址,然后就可以读出window.name的值了。这个方式非常适合单向的数据请求,而且协议简单、安全。不会像JSONP那样不做限制地执行外部脚本。

server proxy

在数据提供方没有提供对JSONP协议或者 window.name协议的支持,也没有对其它域开放访问权限时,我们可以通过server proxy的方式来抓取数据。例如当www.a.com域下的页面需要请求www.b.com下的资源文件asset.txt时,直接发送一个指向 www.b.com/asset.txt的Ajax请求肯定是会被浏览器阻止。这时,我们在www.a.com下配一个代理,然后把Ajax请求绑定到这个代理路径下,例如www.a.com/proxy/, 然后这个代理发送HTTP请求访问www.b.com下的asset.txt,跨域的HTTP请求是在服务器端进行的,客户端并没有产生跨域的Ajax请求。这个跨域方式不需要和目标资源签订协议,带有侵略性,另外需要注意的是实践中应该对这个代理实施一定程度的保护,比如限制他人使用或者使用频率。

双向跨域

document.domain

通过修改document的domain属性,我们可以在域和子域或者不同的子域之间通信。同域策略认为域和子域隶属于不同的域,比如www.a.com和 sub.a.com是不同的域,这时,我们无法在www.a.com下的页面中调用sub.a.com中定义的JavaScript方法。但是当我们把它们document的domain属性都修改为a.com,浏览器就会认为它们处于同一个域下,那么我们就可以互相调用对方的method来通信了。

FIM——Fragment Identitier Messaging

不同的域之间,JavaScript只能做很有限的访问和操作,其实我们利用这些有限的访问权限就可以达到跨域通信的目的了。FIM (Fragment Identitier Messaging)就是在这个大前提下被发明的。父窗口可以对iframe进行URL读写,iframe也可以读写父窗口的URL,URL有一部分被称为frag,就是#号及其后面的字符,它一般用于浏览器锚点定位,Server端并不关心这部分,应该说HTTP请求过程中不会携带frag,所以这部分的修改不会产生HTTP请求,但是会产生浏览器历史记录。FIM的原理就是改变URL的frag部分来进行双向通信。每个window通过改变其他 window的location来发送消息,并通过监听自己的URL的变化来接收消息。这个方式的通信会造成一些不必要的浏览器历史记录,而且有些浏览器不支持onhashchange事件,需要轮询来获知URL的改变,最后,URL在浏览器下有长度限制,这个制约了每次传送的数据量。

Flash LocalConnection

页面上的双向通信也可以通过Flash来解决,Flash API中有LocalConnection这个类,该类允许两个SWF之间通过进程通信,这时SWF可以播放在独立的Flash Player或者AIR中,也可以嵌在HTML页面或者是PDF中。遵循这个通信原则,我们可以在不同域的HTML页面各自嵌套一个SWF来达到相互传递数据的目的了。SWF通过LocalConnection交换数据是很快的,但是每次的数据量有40kb的大小限制。用这种方式来跨域通信过于复杂,而且需要了2个SWF文件,实用性不强。

window.postMessage

window.postMessage是HTML5定义的一个很新的方法,这个方法可以很方便地跨window通信。由于它是一个很新的方法,所以在很旧和比较旧的浏览器中都无法使用。

Cross Frame

Cross Frame是FIM的一个变种,它借助了一个空白的iframe,不会产生多余的浏览器历史记录,也不需要轮询URL的改变,在可用性和性能上都做了很大的改观。它的基本原理大致是这样的,假设在域www.a.com上有页面A.html和一个空白代理页面proxyA.html, 另一个域www.b.com上有个页面B.html和一个空白代理页面proxyB.html,A.html需要向B.html中发送消息时,页面会创建一个隐藏的iframe, iframe的src指向proxyB.html并把message作为URL frag,由于B.html和proxyB.html是同域,所以在iframe加载完成之后,B.html可以获得iframe的URL,然后解析出 message,并移除该iframe。当B.html需要向A.html发送消息时,原理一样。Cross Frame是很好的双向通信方式,而且安全高效,但是它在Opera中无法使用,不过在Opera下面我们可以使用更简单的 window.postMessage来代替。

总结

跨域的方法很多,不同的应用场景我们都可以找到一个最合适的解决方案。比如单向的数据请求,我们应该优先选择JSONP或者window.name,双向通信我们采取Cross Frame,在未与数据提供方没有达成通信协议的情况下我们也可以用server proxy的方式来抓取数据。

原文链接:http://www.woiweb.net/10-cross-domain-methods.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/276703.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

好用的shell工具_精选5个酷毙的Python工具

来自:Python之禅工欲善其事必先利其器,一个好的工具能让起到事半功倍的效果,Python社区提供了足够多的优秀工具来帮助开发者更方便的实现某些想法,下面这几个工具给我的工作也带来了很多便利,推荐给追求美好事物的你。…

承载辉煌历史 畅想无线未来

看了JustDI的文章“手机也能当电脑用?--谈谈未来智能手机操作系统的走向”,作为嵌入式爱好者,我也想谈谈自己的看法。首先,从网络发展的角度看,移动互联网的宽带化,宽带互联网的移动…

接口码释义

1xx:信息,请求收到,继续处理 2xx:成功,行为被成功地接受、理解和采纳 3xx:重定向,为了完成请求,必须进一步执行的动作 4xx:客户端错误,请求包含语法错误或…

java读取文件内容,文件头有\ufeff

"\ufeff"是UTF-8 BOM编码的文件头,代表该文件按照什么字节顺序排序 调用java的工具类[ UnicodeInputStream ]即可解决这个问题 //第二个参数targetEncoding为null时在getDetectedEncoding方法中会自动检测编码类型 UnicodeInputStream unicodeInputStrea…

6款国内外SNS开源软件 搭建社交网站利器

SNS(Social Network Service),有时称为社交网络,有时称为社会化网络,专指旨在帮助人们建立社会性网络的互联网应用服务。如果对SNS概念还很模糊,说到人人网、开心网你就明白了。 去年360圈、蚂蚁网接连关站给SNS前景蒙上一层阴影&…

aop实现原理_从宏观的实现原理和设计本质入手,带你理解 AOP 框架的原理

点击上方“Java知音”,选择“置顶公众号”技术文章第一时间送达!作者:FeelsChaoticjuejin.im/post/5c57b2d5e51d457ffd56ffbb前言本文将从另一个角度讲解 AOP,从宏观的实现原理和设计本质入手。大部分讲 AOP 的博文都是一上来就罗…

孟宪会老师推荐的一部C#图解教程

Amazon五星级盛誉 C# 最新特性一览无余 数十年开发与教学经验的结晶 图、表和文字完美结合,最易学的C# 教程 本书详细信息:http://www.china-pub.com/43556 微软4大名著评选结果揭晓:http://www.china-pub.com/static07/0812/jsj_micrmingz_0…

Python数据分析Numpy库方法简介(三)

补充: np.ceil()向上取整 3.1向上取整是4 np.floor()向下取整 数组名.resize((m,n)) 重置行列 基础操作 np.random.randn()符合正态分布(钟行/高斯)的数据 矩阵的水平拼接 np.vstack((a,b)) 矩阵的垂直拼接 np.hstack((a,b)) 点阵积: np.dot(a,b)/ ab…

xxl-job源码分析

xxl-job源码分析 xxl-job 系统说明 安装 安装部署参考文档:分布式任务调度平台xxl-job 功能 定时调度、服务解耦、灵活控制跑批时间(停止、开启、重新设定时间、手动触发) XXL-JOB是一个轻量级分布式任务调度平台,其核心设计目标是…

定制jQuery File Upload为微博式单文件上传

原文链接:http://avnpc.com/pages/single-file-upload-component-by-jquery-file-upload jQuery File Upload是一个非常优秀的上传组件,主要使用了XHR作为上传方式,并且利用了相当多的现代浏览器功能,所以可以实现诸如批量上传、超…

vb趣味编程弹球小游戏_最好玩的微信小游戏集合,总有一款是你没玩过的

大家好,这里是小雅龙生活趣味时间,自从17年微信推出小游戏程序以来,微信小游戏行业可谓是炙手可热,知道2019年不断有许许多多的微信小游戏如雨后春笋般的生根发芽。下面就由我带大家来看看今年最好玩,最受欢迎的微信小…

開發MOSS2007 Masterpage的一些經驗

一直在做MOSS平臺的Masterpage開發,碰到很多的問題,總結了一些經驗,特此記錄: masterpage的所有的ContentPlaceholder詳細解釋見以下網址:http://www.cnblogs.com/WinYoung/archive/2007/06/25/791766.html 1.如果應用masterpage以后IE狀態欄出現""網頁指令碼錯誤訊息…

Golang——垃圾回收GC(2)

1 垃圾回收中的重要概念 1.1 定义 In computer science, garbage collection (GC) is a form of automatic memory management. The garbage collector, or just collector, attempts to reclaim garbage, or memory occupied by objects that are no longer in use by the pro…

java gui框架_推荐!程序员整理的Java资源大全

构建这里搜集了用来构建应用程序的工具。Apache Maven:Maven使用声明进行构建并进行依赖管理,偏向于使用约定而不是配置进行构建。Maven优于Apache Ant。后者采用了一种过程化的方式进行配置,所以维护起来相当困难。Gradle:Gradle…

帆软报表(finereport)控件背景色更改

setTimeout(function() {$(.fr-trigger-btn-up).css({"background-color": "#003399" });}, 100); 转载于:https://www.cnblogs.com/Williamls/p/11571586.html

开心网分析,师从“中国缘”

作者:麦田   一,师从“中国缘” 开心网从08年“爆发”之后,网上出现很多评论文章。几乎100%的评论文章都谈到了开心网“不可思议”的爆发增长速度,比如几个月就进入了alexa前500等等。但是,几乎没有一篇文章提到“开心…

HTML5+CSS3+JQuery1.9 输入框切换和Div失焦模拟

Div失焦原理&#xff1a;判断document点击对象是否在Div容器以内&#xff0c;否则触发事件 需要脚本&#xff1a;jquery-1.9.1.js 下载地址&#xff1a;http://download.csdn.net/detail/dmtnewtons/5807757 <!DOCTYPE> <html> <head> <meta http-equ…

资本冬天已至,开发者却可以着眼未来

云&#xff0c;在国内外都已成为软件开发者的首选服务。纵观历史&#xff0c;在云计算发展的这些年里&#xff0c;不管云上做了多少产品和服务&#xff0c;其实都离不开云最本质的价值体系&#xff1a;自服务、高弹性、按需提供、免运维&#xff0c;这些特性也让云服务天然成为…

mybatis 大于_酸爽!IDEA 中这么玩 MyBatis,让编码速度飞起!

作者&#xff1a;Orsoncnblogs.com/java-class/p/6237564.html1. 搭建 MyBatis Generator 插件环境a. 添加插件依赖 pom.xmlb. 配置文件 generatorConfig.xmlc. 数据库配置文件 jdbc.propertiesd. 配置插件启动项2.项目实战a. 比如在一个项目 我们要删除某个小组下某个用户的信…

Java的三种代理模式完整源码分析

Java的三种代理模式&完整源码分析 Java的三种代理模式&完整源码分析 参考资料&#xff1a; 博客园-Java的三种代理模式 简书-JDK动态代理-超详细源码分析 [博客园-WeakCache缓存的实现机制](https://www.cnblogs.com/liuyun1995/p/8144676.html) 静态代理 静态代理在使…