资讯专栏INFORMATION COLUMN

js中几种跨域的方法

XboxYan / 520人阅读

摘要:四通过跨域一个页面嵌入一个外域的页面虽然两个窗体之前能获取彼此的对象,但是却拿不到上的属性和方法,例如一个页面嵌入一个的我是父窗体的方法嵌入的窗体跟的域名不同,很明显是跨域的,虽然能获取到对象,但是拿不到页面的任何方法和属性。

js跨域是指通过js在不同域之间进行相互通信或者数据传输,只要协议,域名,端口号其中有一个不同,就是跨域。下面总结一下我了解到的常用的跨域方法。

一:通过jsonp跨域

js通过script标签引入一个外域的资源是不受限制的,jsonp就是利用这个原理,来实现跨域的。



callback是前后台约定的查询参数,服务器端返回一个能执行的js文件,这个js文件是调用callback对应的参数值即getPrice执行,并且返回对应的数据,我们可以在getPrice方法里面来处理返回的数据,最终返回的结果如下

getPrice({
"data":{"priceType":"0","unit":"斤"},
"message":"价格获取成功!!!",
"state":"1"
 })
 

jsonp的原理就是这样,通过Script标签引入一个js文件,这个js文件加载成功会执行callback对应的指定方法,并且把我们需要的数据作为参数传入,jsonp是需要服务器端配合的。

 $.ajax({
   url:"http://wsdetail.b2b.hc360.com/getSupplyPrice",
   dataType:"jsonp",
   data:{bcid:"47296567"},
   jsonp:"callback",
   jsonpCallback:"getPrice",
   success:function(data){
      console.log(data);
   }
 })

下面是使用jquery的jsonp请求,jsonp只能是get请求,在jquery中jsonpCallback可以省略不写,jquery会自动生成一个全局函数替换callback=对应的全局函数,取到数据会自动销毁这个全局函数;jsonp参数用来替换“callback=?”中的callback
比如 {jsonp:"callbackOnload"},会生成"?callbackOnload=getPrice"传给服务器端;

二: 使用XMLHttpRequest对象跨域获取数据
 var xhr = new XMLHttpRequest();

    if ("withCredentials" in xhr) {
        xhr.withCredentials = true;
    }

    xhr.open("post", "https://api.growingio.com/v2/9c75e186a1a30142/web/action?stm=1499731328375", true); //true表示异步请求,如果是false则是同步请求,

    xhr.onreadystatechange = function () {
        if (xhr.readyState == 4) {
            if (xhr.status == 200) {
                var response = xhr.responseText;
                console.log(response)
            }
        }
    };

    xhr.send("data");

XMLHttpRequest最关键部分在服务器部分 ,其实无论是否跨域,服务器都是可以获取上述请求的。问题的关键在于服务器的回应是否能够返回到浏览器。所以在服务器发送回应的时候,需要添加一个文件头。这个文件头的第一个参数是允许跨域,第二个参数是接受跨域的服务,

Access-Control-Allow-Origin:http://a.text.com

其实与不同的XMLHttpRequest还有一个小小的不同,却很重要。同域内的XMLHttpRequest访问通常只有一次请求,而跨域的XMLHttpRequest有两次。

第一次XMLHttpRequest请求,其method是OPTIONS,并非前文定义的POST。这并不是由JS代码控制的,而是浏览器来完成的操作。其作用是判断该请求是否能够被服务器所响应。

第二次XMLHttpRequest请求才是真正的POST请求,包含了上传的文件内容。

这里只是对 CORS 做一个简单的介绍,如果想更详细地了解其原理的话,可以看看下面这篇文章:

阮一峰 跨域资源共享 CORS 详解

下面介绍三种通过 iframe 跨域与其它页面通信的方式。

三: 使用html5的postMessage和onmessage

postMessage 是H5新增的api可以使用它来向其它的window对象发送消息,无论这个window对象是属于同源或不同源,目前IE8+、FireFox、Chrome、Opera等浏览器都已经支持window.postMessage方法。
第一个参数是要发送的数据,第二个参数是接受消息的域,如果不想限定,可以使用通配符"*"

  
  
  

b.text.com域名接受消息的时候需要通过监听onmessage事件,来获取传过来的消息,消息内容存储在事件对象的data属性中。

   window.onmessage=function (e) {
           e=e||event;
           alert(e.data);
           window.parent.postMessage("1234","*")
       }
四:通过document.domain跨域

一个页面嵌入一个外域的iframe页面,虽然两个窗体之前能获取彼此的window对象,但是却拿不到window上的属性和方法,例如一个http://a.text.com/index.html页面嵌入一个http://b.text.com/index.html的iframe

  
  

嵌入的窗体跟a.text.com的域名不同,很明显是跨域的,虽然能获取到window对象,但是拿不到b页面的任何方法和属性。b页面可以用window.parent拿到父窗体,但是也是同样不能拿到任何方法和属性。这个时候用document.domain可以解决这种问题
我们在b页面设置document.domain,在a页面也设置document.domain,document.domain设置也是有限制的,我们只能把domain设置成自身或者更高一级的父域。主域必须相同

  document.domain="text.com";
  function dialog() {
          alert("ifram里面的方法")
      }
  window.parent.parentAlert()

我们在a页面也设置一下domain, document.domain="text.com"; 两个窗体之间可以正常通信了,这就是通过domain跨域获取数据,这种方式只适合两个窗体之前,不适合ajax请求;

五:使用 window.name 属性

window对象有一个name属性,在一个窗口生命周期内,所有载入的页面共享这个name属性,并且都有对这个name的读写权限。比如有一个页面 http://a.text.com/index.html

 window.name="我是index页面设置的name属性";
  setTimeout(function () {
      window.location.href="http://b.text.com/index.html";
  },3000)
  

3秒后载入了b页面,在b页面我们获取window.name,成功的获取到了index页面设置的window.name的值,需要注意的是window.name只能是字符串形式,大小2M左右,下面就来看看具体怎样通过window.name跨域获取数据

在http://my.b.text.com/index.html页面嵌入一个iframe,

 var _iframe=document.createElement("iframe");
     _iframe.src="http://b.text.com/index.html";
     _iframe.style.display="none";
     document.body.appendChild(_iframe);
 
     _iframe.onload=function () {
 
         _iframe.src="about:blank;";
 
         _iframe.onload=function () {
             alert(_iframe.contentWindow.name);
         }
     }

http://b.text.com/index.html页面设置window.name

    window.name="iframe数据"

在http://my.b.text.com/index.html页面请求http://b.text.com/index.html页面的数据,我们可以在页面建立一个iframe,src指向请求的地址,利用iframe的跨域能力
在请求的页面设置window.name的值。 但是由于 my.b.text.com 页面和该页面 iframe 的 src 如果不同源的话,则无法操作 iframe 里的任何东西,所以就取不到 iframe 的 name 值,所以我们需要在 b.text.com 加载完后重新换个 src 去指向一个同源的 html 文件,或者设置成 "about:blank;"
改变iframe的src指向后,这个时候在监听iframe的onload属性,就可以获取到iframe的window.name属性了;

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/87152.html

相关文章

  • 跨域方式实现原理(完整版)

    摘要:二跨域解决方案原理利用标签没有跨域限制的漏洞,网页可以得到从其他来源动态产生的数据。使用反向代理实现跨域,是最简单的跨域方式。 前言 前后端数据交互经常会碰到请求跨域,什么是跨域,以及有哪几种跨域方式,这是本文要探讨的内容。 本文完整的源代码请猛戳github博客,纸上得来终觉浅,建议动手敲敲代码 一、什么是跨域? 1.什么是同源策略及其限制内容? 同源策略是一种约定,它是浏览器最核心...

    edgardeng 评论0 收藏0
  • 跨域方式实现原理(完整版)

    摘要:二跨域解决方案原理利用标签没有跨域限制的漏洞,网页可以得到从其他来源动态产生的数据。使用反向代理实现跨域,是最简单的跨域方式。 前言 前后端数据交互经常会碰到请求跨域,什么是跨域,以及有哪几种跨域方式,这是本文要探讨的内容。 本文完整的源代码请猛戳github博客,纸上得来终觉浅,建议动手敲敲代码 一、什么是跨域? 1.什么是同源策略及其限制内容? 同源策略是一种约定,它是浏览器最核心...

    justCoding 评论0 收藏0
  • javascript中实现跨域的方式总结

    摘要:中的跨域请求应该也算是一个重点,具体什么叫跨域,在这里我就不展开了,可以查一下浏览器的同源策略和跨域的定义。再看后台文件文件接收回调函数并把要返回的参数以参数注入的方式注入到回调函数中,再返回给客户端。 js中的跨域请求应该也算是一个重点,具体什么叫跨域,在这里我就不展开了,可以查一下浏览器的同源策略和跨域的定义。原来只知道常用的jsonp和document.domain这两种方式,这...

    VioletJack 评论0 收藏0
  • 「JavaScript」JS两种服务端相关跨域方法详解

    摘要:之前我们讲了一下四种跨域的方式四种跨域方式详解。这四种方式是使用纯来进行跨域的。今天就介绍两种有涉及到服务器的跨域技术。 之前我们讲了一下四种 JavaScript 跨域的方式 - 「JavaScript」四种跨域方式详解。这四种方式是使用纯 JavaScript 来进行跨域的。 今天就介绍两种有涉及到服务器的跨域技术。 一、反向代理服务器 基础思想很简单,将你的服务器配置成 需要跨域...

    kid143 评论0 收藏0

发表评论

0条评论

XboxYan

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<