HTTP请求跨域问题,解决模棱两可。

什么是跨域?就不说了,一搜一大堆。

就讲讲如何跨域,本文对一些前辈的博客进行总结精简,尽量简洁的表述粗来。

一、CORS微笑

是W3C制定的为解决跨域请求的一个规范。直接上代码

var xhr = new XMLHttpRequest();
    xhr.open("GET", "http://www.a.com",true);
    xhr.send();


其实很简单,即发送请求时,请求头中有一个"origin:http://www.b.com."

服务器响应头中返回"Access-Control-Allow-Origin:http://www.b.com 或 *"

"Access-Control-Request-Method":"PUT,POST"

即表示跨域请求允许,请求成功生气

如果在回应的头信息中没有"Access-Control-Allow-Origin"字段则会报错,请求失败哭

优点:支持所有请求方式;方式简单。

缺点:低级古老的浏览器不支持。

二、服务器代理请求微笑

顾名思义,就是首先请求同域服务器,给同域服务器代理脚本,由代理脚本来完成跨域请求然后把结果返回客户端。

优点:支持GET和POST

缺点:处理复杂

三、JSONP方式微笑

<script type="text/javascript">
    function callFunc(data){
        //处理获得的json数据
	console.log(data);
    }
</script>
<script src="http://example.com/data.php?callback=callFunc"></script>

因为src的url是一个后台脚本访问后会被执行,返回的JSON以字符串形式包含在回调函数中,

返回的字符串放入script标签中则执行回调函数,返回的JSON数据也作为实参传入了回调函数。

以上应该算是比较常见的JSONP的原生实现方法,也有一些对此做了封装的框架,比如jquery如下:

$.ajax({
  type : "GET",
  url : "http://zhangzhanyu.nfreehost.com/jsonp.php",
  dataType : "jsonp",
  success : function(json) {
    alert(json.msg);
  }
});


请千万不要被jquery对JSONP的封装为$.ajax就误以为JSONP的跨域访问也是AJAX请求,其实两者一点关系都没有!!

我从一篇文章中看到过有人推荐的一种插件(fetch-jsonp

fetchJsonp(Url)
.then(response => {return response.json();})
.then(json => {resolve(json);})
.catch(err => {reject({errMsg: '调用接口失败', success: false});})


利用script标签支持跨域的特性,实现跨域请求。

优点:古老的浏览器也支持

缺点:仅支持GET

四、利用iframe完成跨域请求微笑

举个栗子,父页面(http://a.test.com/a.html)中嵌入iframe子页面(http://b.test.com/b.html

父页面(http://a.test.com/a.html)代码:

<iframe id = "iframe" src="http://b.test.com/b.html" onload = "loadIframeData()"></iframe>


下面讲下如何在两个页面之间发送和接收数据:
发送数据:
 A(父页面) -> B(iframe):

document.getElementById('iframeId').contentWindow.postMessage(JSON.stringify(data), '*'); 


第一个参数传递的数据json化,第二个指定允许接收的域名,*表示允许任意域名
B(iframe )-> A(父页面):

window.parent.postMessage(JSON.stringify(data), '*');


父子页面监听接收数据

if (window.addEventListener) {
  window.addEventListener('message', function(event) {
    if(event.origin == '父页面url'){
try {
          const data = JSON.parse(event.data);
    } catch(e) {
    }
  }, false);
}else{
  window.attachEvent('onmessage',funtion(event){
    if(event.origin == '父页面url'){
try {
          const data = JSON.parse(event.data);
    } catch(e) {
    }
  }, false);
}


优点:通过iframe去完成跨域有其最显著的优势,就是在A页面向B服务器去进行跨域请求时,B服务器需要进行比较多的处理才能返回结果的时候,利用iframe去完成是非常好用的。缺点:如果iframe页面中有页面跳转的情况下,用户想回退父页面出现的结果是iframe页面回退了,但父页面URL和页面都没发生变化(需要在跳转前remove当然iframe,然后重新插入iframe到新的src,防止污染父页面url)。另外这样的做法有时候像多了一层代理,因此一方需求改动,则需要更改比较多的地方。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值