在IE8,9浏览器下,有能实现没有跨域访问权限 ie8同步请求的技术吗

通过 XHR Level2 以及 IE XDR (XDomainRequest) 实现AJAX跨域 - 推酷
通过 XHR Level2 以及 IE XDR (XDomainRequest) 实现AJAX跨域
以往遇到AJAX跨域需求时都会采用服务器端代理,或者改用JSONP, &window.name,postMessage() 等方法模拟,但都不是很纯粹的AJAX解决方案。今天学到了新的实现跨域的方法。
XHR Level2
HTML5中&XMLHttpRequest Level 2 的推出。可以通过在返回的HTTP请求头中加入&Access-Control-Allow-Origin 的设置,让浏览器支持对不同域的AJAX请求。这个情况下前端AJAX的代码不用做任何更改,只需要在服务端的返回中设置以下头信息即可:
Access-Control-Allow-Origin: * //*代表任何域。也可以指定地址
Access-Control-Allow-Methods:&POST,GET //支持的方法
header( & Access-Control-Allow-Origin: * & );
header( & Access-Control-Allow-Methods: POST,GET & );
另外XHR2也带有更多高级功能,例如progress进度,文件上传,获取二进制数据等。详见&
XDR (IE 8-9 Only)
对于XHR2,IE浏览器的支持是IE10以上。但是IE早在IE8时就推出了&XDomainRequest 对象进行跨域操作,一直沿用到IE10才被取代掉。因此在IE8,IE9中应该使用&XDomainRequest (XDR)来实现。
XDR在创建时是通过&new XDomainRequest() 进行创建。其他操作和XHR有细微差别。比如open方法只有method和url两个参数,XDR只支持异步不支持同步操作。详细见文档:
var xdr = new XDomainRequest();
xdr.open(&get&, &&);
xdr.onload = function() {
//success(xdr.responseText);
xdr.send();
另外使用XDR时也需要服务器端设置上面提到的&Access-Control-Allow-Origin 头信息。
已发表评论数()
已收藏到推刊!
请填写推刊名
描述不能大于100个字符!
权限设置: 公开
仅自己可见
正文不准确
标题不准确
排版有问题
没有分页内容
图片无法显示
视频无法显示
与原文不一致打酱油震惊呵呵赞鄙视标签: ,,注:与内容无关的评论将被删除,严重者禁用帐号! | 最新评论不吐不快,赶紧来一发!栏目推荐关注 第一PHP社区 微信公众号热门点击本站推荐
| 中国最专业的PHP中文社区 |
Copyright (C) 1998 - . All Rights Reserved
第一PHP社区
版权所有 七牛云存储为本站提供加速支持 &&&&&> js最全的十种跨域解决方案
js最全的十种跨域解决方案
lanpier511 & &
发布时间: & &
浏览:44 & &
回复:0 & &
悬赏:0.0希赛币
js最全的10种跨域解决方案
  在客户端编程语言中,如javascript和ActionScript,同源策略是一个很重要的安全理念,它在保证数据的安全性方面有着重要的意义。同 源策略规定跨域之间的脚本是隔离的,一个域的脚本不能访问和操作另外一个域的绝大部分属性和方法。那么什么叫相同域,什么叫不同的域呢?
  同源策略
  在客户端编程语言中,如javascript和 ActionScript,同源策略是一个很重要的安全理念,它在保证数据的安全性方面有着重要的意义。同源策略规定跨域之间的脚本是隔离的,一个域的脚本不能访问和操作另外一个域的绝大部分属性和方法。那么什么叫相同域,什么叫不同的域呢?当两个域具有相同的协议(如http), 相同的端口(如80),相同的host(如),那么我们就可以认为它们是相同的域。比如 和是同域,而, , , 中的任何两个都将构成跨域。同源策略还应该对一些特殊情况做处理,比如限制file协议下脚本的访问权限。本地的HTML文件在浏览器中是通过file协议打开的,如果脚本能通过file协议访问到硬盘上其它任意文件,就会出现安全隐患,目前IE8还有这样的隐患。
  受到同源策略的影响,跨域资源共享就会受到制约。但是随着人们的实践和浏览器的进步,目前在跨域请求的技巧上,有很多宝贵经验的沉淀和积累。这里我把跨域资源共享分成两种,一种是单向的数据请求,还有一种是双向的消息通信。接下来我将罗列出常见的一些跨域方式,以下跨域实例的源代码可以从这里获得。
  单向跨域
  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的方式来抓取数据。
  本文永久链接地址:
本问题标题:
本问题地址:
温馨提示:本问题已经关闭,不能解答。
暂无合适的专家
&&&&&&&&&&&&&&&
希赛网 版权所有 & &&如何解决 Ajax 跨域请求不到的问题?
希望最好用原生js,可以掠去ajax方法体,而且能满足post需求,另外,请不要直接拷网上的“滥”了的文章。。。谢谢增加一個問題:我要用JS獲取一個網頁上面的內容, 一個JSON. 格式只能是: {'id' : xxx}. 我試過JSONP不成=.= iframe的話, JS又訪問不了iframe內容(因為跨域). 又不可以用代理. 因為要用戶身份認證.求教呀
按投票排序
lz,不要多想了,如果要请求的服务器不是你控制的,那基本不可能了。如果你可以控制要请求的服务器,那完全可以定制虾 用jsonp。什么iframe,window。name也都用不着了。。。
既然这样,为何舍近取远呢?这才叫做最原生的处理方法。方法1
服务器端直接设置header内容
Access-Control-Allow-Origin:*
Access-Control-Allow-Origin:htt@p://
这样就可以直接请求到任何网站或者htt@p://php程序这样写:
header('Access-Control-Allow-Origin:*');或者
header('Access-Control-Allow-Origin:htt@p://');(注意去掉@,知乎编辑器不知道怎么不让带http的网址自动链接,先这样写了)方法2
在Nginx设置”头信息“直接添加Access-Control-Allow-Origin:*的信息。
尽量让前端简化吧 在我看来最简单最直接的方案不过两种:1. 配置目标服务器的CORS 2. 如果觉得CORS有学习成本,最简单的办法就是加一个“转发”的路由,注意这里不是“跳转”,因为跳转同样会遇到跨域问题。
除非你有数据的控制权,能通过 JSONP 或者 CORS 等方法拿到数据,否则肯定没戏。这是个浏览器的原则问题,如果有跨域方法那肯定是浏览器漏洞,早晚会被修复。在一些上古浏览器里可以使用上古漏洞,修改 Object 或 Array 的构造函数来进行 JSON 劫持。就像这样:&script&
Object.prototype.__defineSetter__('id', function(obj) {
alert(obj);
&script src="/test.json"&&/script&
这样就会弹出 test.json 中所有 key 为 “id” 的值。或者这样:var arrData;
Array = function() {
arrData = this;
这样通过 arrData 也能访问到 JSON 数据。现代浏览器早就把这些漏洞封死了,如果你能找到可以在前端劫持 JSON 的通用漏洞,那卖给黑产小哥都够你大赚一笔的了。
jsonp 是写 script 标签,只能满足 get 请求。跨域 post 的话,IE8 及以上和其他主流浏览器可以用 window.postMessage 来实现,也就是传说中的 HTML5 方法了,可以看下标准,代码很简单。IE6、7 就用老式的方法,隐藏的 form,target 指向一个隐藏的 iframe,然后调 form 的 submit,服务端返回的结果会刷到 iframe 里。不过这两种方法一般都需要服务端做一定的配合,要是不能操作接口所在的服务器(比如调第三方的接口),那就只能在自己的服务端上做代理了。
所有使用JSON的方案都有一个错误,就是无法实现POST。那目前实现POST的方法是1、建立一个iframe,iframe内的JS创建一个form表单,并可以将接收到的参数放入表单中POST提交。2、将iframe页面插入到页面中。3、针对现代浏览器,将数据通过postMessage()方法传入iframe中。针对不支持此方法的浏览器,通过URL HASH的方法将参数传入iframe中。(由于URL有长度限制,所以不能传播大数据)除此方法外,可以使用window.name的方案,但此方案我没有实现过,具体可以百度一下张克军写的事例。
使用json,就是使用 & script & 标签,实现伪ajax.我一般使用jq.给你个jq的例子.$.ajax({
dataType:'jsonp',
timeout : 3000 ,//毫秒
data : 'foo=bar1&foo=bar2',
//jsonpCallback:'jsoncallback',
beforeSend
:function(){
error:function(item){
alert('加载失败');
success: function(item){
alert( item.items[0].media.m);
complete: function(){}});json.php& ?phpheader('Content-type: application/json');$results = array("key" = &
"value",'key1'= & array('a'= & 'ok'));echo $_GET['callback'] . '(' . json_encode($results) . ')';? &
跨域问题,目前地球上最好、最方便(没有之一)的解决方案是,利用Apache转发。原因有2:1.前台后台的代码都不需要改动,也不需要为跨域去专门写代码或改代码。2.Apache非常容易安装:Win上有WAMP,Linux上有LAMP;且Apache的转发设置起来非常简单方便。开发时甚至可以直接把转发配置为客户端到VS或Eclipse,方便调试;上线后把转发切换成客户端到Apache自身或IIS或Tomcat或WebLogic或Nginx等等。
首先假设你请求数据的网站为B。要看你是否可以控制(修改里面的代码)。1
缺点 只能get请求 ,需要修改B网站的代码2 cors 说的方案,这个方案缺点 是 ie6 7 兼容不好(倒是不见得要兼容)。需要B网站在响应中加头3 postMessage
缺点也是 ie6 7 兼容不好(倒是不见得要兼容)。需要修改B网站的代码4 iframe window.name 传值得方式很巧妙,兼容性也很好。但是也是需要你能修改B网站代码5 服务端主动请求B网站,兼容性好而且你客户端的代码还是原来的ajax,缺点是感觉不好。。6 类似5 用nginx把B网站的数据url反向代理。我觉得吧,如果你不能修改B网站的代码老老实实5 6 方案如果能修改B网站 方案2的修改应该是最简单的。就算是B网站你可以修改,还有种需求处理起来比较麻烦的,就是有的数据需要登录之后才能取。最直接的方案,B网站提供数据的url 进去先提供用户名密码,走下登录再走取数据,最后返回数据。但是往往最直接的方案都不是好的方案。。。(登录请求=》返回令牌=》带令牌请求受限数据)所以最好用是方案2
然后B网站有oauth 功能,你的页面加个登陆后,用户登陆后客户端保存好token_key,然后取数据。(这个方案类似通过sessionid得到session。因为安全相关的原因,通过通过sessionid得到session 这样的需求并不是所有语言的所有框架都会提供的)当然oauth方案也有坏处,就是B网站本来没有oauth,要加上一个会略麻烦。所以还可以选择方案2 加上withcredentials=true 这个方案。当然登录页面还是需要的这个问题已经是4年前的了,不过跨域请求似乎是个永恒的问题,正好最几天刚刚也遇到了类似的需求,就写得多了一点了。最近需要将原来的一个web网站写成手机版本,我是用的html5 加cordova 打包成手机程序的, 方案2
然后加withcredentials=true 然后在登录请求后重写手机客户端的cookie 方案能很好满足我的需求。 希望对大家有帮助
jsonp对内容的长度有限制,最多也就能传几百字节。要大量内容的话,只能创建一个form,动态输入input,然后调用它的submit方法。将submit的结果放到一个iframe中,就可以显示返回值。 p.s 目前看到最好的跨域解决方案是window.name跨域传递,可以无缝传输最大2M的数据。具体方案见:
已有帐号?
无法登录?
社交帐号登录[web前端]跨域通信与实验 – zcw的博客}

我要回帖

更多关于 jquery ajax ie8 跨域 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信