跨域问题

本文深入解析跨域问题,介绍JSONP、iframe、代理服务器及CORS四种常见解决方法,探讨各自优缺点,助你掌握跨域请求的核心技术。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

引言

跨域,顾名思义,就是一个域发送请求访问另一个域。

什么是域?

域就是协议名(如http)+主机名(如www.baidu.com)+端口号(如80)。只有这三部分一样,才能算是同一个域

跨域的方法常用的有四种:分别是JSONP、iframe标签跨域、代理服务器跨域、CORS跨域

JSONP跨域

众所周知,在HTML页面中的< img >、< link >、< script >等标签的src属性是不受跨域请求限制。所以我们可以通过动态生成

// 动态创建script标签
var script = document.createElement('script');
// 随机生成函数名,不然会读取本地缓存的js文件
var time = new Date();
var funcName = 'jsonp'+time.getTime();

// 拼接URL,判断URL中是否传有参数
if(url.indexOf('?')>0){
    // 如果url中传有参数,这样拼接URL
    url = url + '&callback' + funcnName;
}else{
    // 如果url中没有参数,这样拼接URL
    url = url + '?callback' + funcnName;
}

// 注册回调函数到全局
window[funcName] = function(data){
    callback(data);  // 这里的回调函数自己设定
    //调用完回调函数后销毁我们注册的函数和创建的script标签
    delete window[funcName];
    script.parentNode.removeChild(script);
}


// 设置script标签的src属性
script.setAttribute('src',url);
// 把script标签加入head,请求服务器得到数据
document.getElementsByTagName('head')[0].appendChild(script);

使用JSONP需注意

要注意回调函数的名称。我们需要和后台确定一个callback参数(作确定回调函数名用),方便后台调用前端写的回调函数

JSONP的缺点

①无法发送POST请求
②想确定JSONP请求是否失败并不容易,大多数确定方法都是结合超时时间来判断
③JSONP是可执行脚本,可能存在安全隐患
④对于一些第三方API接口,他们不像和我们约定好的后台那样会读取callback参数。他们只返回JSON或者XML数据,也就是我们平常像后台要的数据一样,只是他是跨域的。这种时候,JSONP形式获取数据就不合适了

iframe标签跨域

这个方法的关键在于window的name属性。该属性的特性在于,同个窗口的所有页面使用的都是同一个window.name属性,并且不会因为刷新和新页面的载入而重置,但是每个页面都可以读取和修改这属性!所以我们可以使用这个属性作为中介,存放接收的数据

// 客户端

<body>
<button onclick="getData()">点击发起跨域请求数据</button>
<iframe id="iframe" src="http://localhost:3000/xxx/xxx/index?name=John" style="display:none"></iframe>
// 只是利用iframe获取跨域数据,所以样式设置不显示
</body>
<script>
function getData(){
// 获取iframe元素
var iframe = document.getElementById('iframe');

// 设置为空白页,就不存在域了(即没有跨域问题),如果不设置的话,iframe的src和本地的是不同域的,也就是还存在跨域问题
iframe.src = 'about:blank'; 

//让iframe重新加载一次,地址就变成我们同域了(任何空白页和任何域都同域)
    iframe.onload = function(){
        // iframe中的contentWindow对象相当于我们正常打开页面的window对象,获取它的name值
        var data = iframe.contentWindow.name;
        data = JSON.parse(data);  // 转为JSON格式
        alert(data.name);
    }   
}
</script>
// 服务端

app.get('/xxx/xxx/index',function(req,res){
   let param = req.query.name;
   var data = {name:param};
   var data = JSON.stringify(data);
   
   res.send('<script>window.name='+data+';</script>');
});
iframe标签跨域缺点

不支持POST访问

代理服务器处理跨域

我们需要知道的是,跨域问题只存在于浏览器中,服务器之间的访问不存在跨域问题。所以我们可以通过后台访问需要跨域访问的url,然后让后台返回数据给前端就行了。

CORS跨域

其是W3C推出的一种新机制,基于浏览器的一个内置机制,需要浏览器支持。所以其实现方法只需要和正常的AJAX一样,不需要额外的代码,浏览器支持该机制的话,就会自动帮你跨域,不支持就会报错。但需要满足以下要求

  • 请求方式要用:HEAD、POST、GET
  • 数据类型 Content-Type 只能是application/x-www-form-unlencoded、multipart/form-data或text/plain中的一种
  • 不使用自定义的请求头
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值