js最全的十种跨域解决方案

 

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

同源策略

  在客户端编程语言中,如javascript和 ActionScript,同源策略是一个很重要的安全理念,它在保证数据的安全性方面有着重要的意义。同源策略规定跨域之间的脚本是隔离的,一个域的脚本不能访问和操作另外一个域的绝大部分属性和方法。那么什么叫相同域,什么叫不同的域呢?当两个域具有相同的协议(如http), 相同的端口(如80),相同的host(如),那么我们就可以认为它们是相同的域。比如 和是同域,而, , , 中的任何两个都将构成跨域。同源策略还应该对一些特殊情况做处理,比如限制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加载。当跨域访问资源时,例如从域请求域上的数据,我们可以借助flash来发送HTTP请求。首先,修改域上的crossdomain.xml(一般存放在根目录,如果没有需要手动创建) ,把加入到白名单。其次,通过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响应头,该响应头声明了请求域的可访问权限。例如对下的 asset.php发送了一个跨域的HTTP请求,那么asset.php必须加入如下的响应头:

  header("Access-Control-Allow-Origin: ");

  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的方式来抓取数据。例如当域下的页面需要请求下的资源文件asset.txt时,直接发送一个指向 /asset.txt的Ajax请求肯定是会被浏览器阻止。这时,我们在下配一个代理,然后把Ajax请求绑定到这个代理路径下,例如/proxy/, 然后这个代理发送HTTP请求访问下的asset.txt,跨域的HTTP请求是在服务器端进行的,客户端并没有产生跨域的Ajax请求。这个跨域方式不需要和目标资源签订协议,带有侵略性,另外需要注意的是实践中应该对这个代理实施一定程度的保护,比如限制他人使用或者使用频率。

  双向跨域

  document.domain

  通过修改document的domain属性,我们可以在域和子域或者不同的子域之间通信。同域策略认为域和子域隶属于不同的域,比如和 su是不同的域,这时,我们无法在下的页面中调用su中定义的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的改变,在可用性和性能上都做了很大的改观。它的基本原理大致是这样的,假设在域上有页面A.html和一个空白代理页面proxyA.html, 另一个域上有个页面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.educity.cn/wenda/53094.html

转载于:https://www.cnblogs.com/highshao/p/5419685.html

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

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

相关文章

剑指offer之二叉树的下一个结点

1 问题 给定一个二叉树和其中的一个结点,请找出中序遍历顺序的下一个结点并且返回。注意,树中的结点不仅包含左右子结点,同时包含指向父结点的指针 2 分析 比如我现在的二叉树如下 42 61 3 5 7 这里分3种情况 1) 如果…

查看和修改系统时间

Echo -n 不换行显示 echo -e不转义Date ‘%Y-%m-%d 查看当前时间 date-s ‘2017/09/04’表示修改时间 %w表示周 %H:%M:%S时分秒 %F%Y-%m-%d %T%H:%M:%S$()反引号 hwclock将修改后的系统时间写到bios里Date %F -d ‘-3 day’三天前 -一定要Date %F -d ‘3 day’三天以后 …

fanuc机器人码垛编程实例_FANUC 机器人码垛编程详细讲解 记得收藏!

原标题:FANUC 机器人码垛编程详细讲解 记得收藏!1. 码垛功能的定义对几个具有代表性的点进行示教,即可以从下层到上层按照顺序堆叠工件。2. 码垛的种类码垛 B:包括码垛B(单路径模式)和码垛BX(多路径模式) 适用于工件姿势恒定,堆叠…

基于casbin的ABAC/RBAC权限实践

五一假期疫情封在家也没事做,就想来优化一下一个前端容器小项目之前的TODOlist里面有一项是权限这块时隔2年了还一直没有动手迟迟没搞主要还是我太懒了,哈哈 其实我一直想要找一个轻量级的权限通用方案权限的数据源可以切换,但是逻辑基本不用…

Python3 实现建造者模式

建造者模式 建造者模式用于创建复杂的对象。使用建造者模式可以使复杂的过程层次明了、清晰,把对象的创建以及使用进行了解耦。实际上从代码的角度上看,是进行了多次封装,使代码结构更为规范合理,层次结构更加鲜明。 在一个复杂…

系列网络服务器机柜,什么是网络机柜 网络机柜和服务器机柜有哪些区别【详解】...

【网络机柜】什么是网络机柜 网络机柜和服务器机柜区别服务器机柜和网络机柜的区别服务器机柜 :用来组合安装面板、插件、插箱、电子元件、器件和机械零件与部件,使其构成一个整体的安装箱。可以配置:专用固定托盘、专用滑动托盘、电源插排、…

JS解析url

使用js解析url ,返回一个对象&#xff0c;使用函数&#xff1a; <script type"text/javascript"> var url"www.taobao.com?key0a&key1b&key2c"; function parseQueryString(url){var strurl.split("?")[1],itemsstr.split("…

Android SDK 目录说明

Android SDK目录说明: AVD Manager.exe&#xff1a;虚拟机管理工具 SDK Manager.exe&#xff1a;sdk管理工具 tools目录&#xff1a;包括测试、调试、第三方工具。模拟器、数据管理工具等。 build-tools目录&#xff1a;编译工具目录&#xff0c;包含了转化为davlik虚拟机的编译…

【3D Max】3D max如何删除环境贴图

问题描述&#xff1a;在用3dm max贴图的时候&#xff0c;如果不选中对象&#xff0c;很容易将图贴到背景环境中去&#xff0c;情况如下所示&#xff1a; 解决办法有二&#xff1a; 一、不参与渲染 快捷键8&#xff0c;在“环境和效果”窗口中去掉“使用贴图”前面的√。 二、…

剑指offer之求二叉树中两个节点的最低共同父节点

1 问题 求二叉树中俩个节点的最低共同父节点&#xff0c;比如二叉树如下 42 61 3 5 7 比如节点1和3两个节点的最低共同父节点是2&#xff0c;节点3和5两个节点的最低共同父节点是4,节点5和6两个节点的最低共同父节点是6, 也有可能其中1个节点或者2个节点不…

C#语法糖系列 —— 第四篇:聊聊 Span 的底层玩法

把 Span 归于语法糖&#xff0c;可能有些偏了&#xff0c;但偏了就偏了&#xff0c;哈哈&#xff0c;只要是分享就好&#xff0c;C# 发展至今&#xff0c;已经是一门非常重的语言了&#xff0c;所有想要的它都要&#xff0c;即可以&#xff1a;面向过程编程面向对象编程面向函数…

hdu 1556 Color the ball 线段树 区间更新

水一下 #include <bits/stdc.h> #define lson l, m, rt<<1 #define rson m1, r, rt<<1|1 using namespace std;const int MAXN 111111; int sum[MAXN<<2]; int n;void push_down(int rt, int len) {if(sum[rt] 0) return;sum[rt<<1] sum[rt];…

【ArcGIS风暴】河流水系左斜体样式经典设置方法

目录 一、效果预览 二、实现方法 一、效果预览 河流水系在作图时一般设置为左斜体、蓝色,如黄河、青海湖、洮河等,如下图所示: 二、实现方法 下面介绍在ArcGIS 10.5中的实现方法。 1、ArcGIS设置方法 绘图工具添加文字或者将标注转为注记,双击,打开属性,点击更改符号…

mlp 参数调优_积神经网络(CNN)的参数优化方法

积神经网络(CNN)的参数优化方法from&#xff1a;http://blog.csdn.net/u010900574/article/details/51992156著名&#xff1a; 本文是从 Michael Nielsen的电子书Neural Network and Deep Learning的深度学习那一章的卷积神经网络的参数优化方法的一些总结和摘录&#xff0c;并…

HBase简介(很好的梳理资料)

HBase HBaseHadoop网络应用数据结构NoSQL 一、 简介 history started by chad walters and jim 2006.11 G release paper on BigTable 2007.2 inital HBase prototype created as Hadoop contrib 2007.10 First useable Hbase 2008.1 Hadoop become Apache top-level project …

python 实现原型设计模式

原型设计模式主要在当新建一个对象的时候&#xff0c;觉得很麻烦&#xff0c;并且你又要保留当前对象。在这种情况下使用原型设计模式是一个很好的解决办法。 例如你写一个东西更新&#xff0c;不同的版本&#xff0c;这个时候以前的版本肯定要保留&#xff0c;并且从此基础上…

装服务器显示磁盘脱机,服务器磁盘处于脱机

服务器磁盘处于脱机 内容精选换一换配置目的端或启动目的端时提示“SMS.1311 目的端磁盘个数不够”。在配置目的端服务器过程中&#xff0c;会校验目的端磁盘数量是否和源端一致。当出现该错误时&#xff0c;检查目的端服务器磁盘数量是否少于源端服务器磁盘数量&#xff0c;或…

百度第三方登录

首先第三方应用要跟微信帐号合作&#xff0c;然后按照下面的方法操作&#xff1a; 目前&#xff0c;百度OAuth2.0支持五种获取Access Token的流程和一种刷新获取AccessToken方式&#xff0c;第三方可根据需求选取合适的方式&#xff1a; 百度授权的Access Token是有有效期的&am…

剑指offer之重建二叉树

1 问题 重建二叉树&#xff1a;给定二叉树的先序遍历&#xff08;根左右&#xff09;和中序&#xff08;左中右&#xff09;遍历结果&#xff0c;建立这棵二叉树。输入保证二叉树无重复结点 以先序{1, 2, 4, 7, 3, 5, 6, 8}和中序{4, 7, 2, 1, 5, 3, 8, 6}为例 2 分析 先序遍…

ArcGIS 10.5专题地图制作自定义漂亮图框

先来看一下效果: 下面来说明如何在ArcGIS软件里面实现自定义图框。 1. 【自定义】→【样式管理器】→【Administrator.style】→【边框】→【新建】→【常规边框】。 2. 点击【更改符号】。 3. 点击【编辑符号】。