跨域解决方案总结

本文介绍了跨域的概念,包括同源策略及其原因,并详细探讨了五种跨域解决方案:JSONP、CORS、window.name、document.domain以及片段识别符。讲解了每种方法的工作原理、优缺点以及应用场景,为开发者提供了全面的跨域处理指南。

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

概念

同源策略

同源策略是浏览器的一种安全策略,所谓同源是指域名、协议、端口完全相同,只有在同源的地址才可以相互通过AJAX的方式请求。

跨域出现的原因

就是当协议、域名、端口任意一个不相同时,都算是不同域,不同域之间相互请求资源,就是“跨域”。

跨域解决方案

方法一、JSONP

JSONP 是一种借助于script 标签发送跨域请求。
原理:就是在客户端借助script标签请求服务端的一个地址,服务端的这个地址返回一段带有调用某个全局函数调用的JS脚本(而非一般的HTML),将原本需要返回客户端的数据通过参数传递给这个函数,函数中就可以得到原本服务端想要返回的数据。
绝大多数情况都是采用JSONP的手段完成不同源地址之间的跨域请求

  • 客户端
    http://www.zce.me/users-list.html
    在这里插入图片描述
  • 服务端
    ** http://api.zce.me/users?callback=foo** 返回的结果
    在这里插入图片描述
JSONP弊端
  • JSONP只能发送GET请求;
  • JSPNP 用的是 script标签,和AJAX 提供的 XMLHttpRequest 没有任何关系;
  • 发送的不是xhr请求,不支持异步方法;
  • 后台需要改动;
jQuery 中对JSONP 支持

jQuery 中使用JSONP就是将dataType 设置为 jsonp
在这里插入图片描述

JSONP方法总结

1、由于XMLHttpRequest 无法发送不同源地址之间的跨域请求,所以我们必须要另寻他法,script 这种方案就是我们最终选择的方式,我们把这种方式称之为 JSONP;
2、JSONP 需要服务端配合,服务端按照客户端的要求返回一段JavaScript 调用客户端的函数;

方法二、CORS ( 跨域资源共享 )
  • 主页:https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Access_control_CORS
  • 原理:只需要向响应头加上一个Access-Control-Allow-Origin 的响应头,表示这个资源是否允许指定域请求,就可以实现跨越操作;
  • 这种方案无需客户端作出任何变化 (客户端不用改代码)
  • 普通跨域请求:只需服务端设置Access-Control-Allow-Origin;
  • 带cookie跨域请求:前后端都需要进行设置;
  • 前后端设置:根据xhr.withCredentiald字段判断是否带有cookie;
  • 服务端设置:服务端对于CORS的支持,主要是通过设置Access-Control-Allow-Origin 来进行的,如果浏览器检测到相应的设置,就可以运行Ajax进行跨域的访问。

在这里插入图片描述

方法三、 window.name
  • window对象有一个name属性,该属性有个特征:就是在一个窗口(window) 的生命周期内,窗口载入的所有页面都是共享一个window.name的,每个页面对window.name 都有读写的权限,window.name是持久存在一个窗口载入过的所有页面中的,并不会因新页面的载入而进行重置。

  • 注意:window.name的值只能是字符串的形式,且这个字符串的大小最大能容许2M左右,甚至更大的容量,因浏览器而异,但是一般的话都是够用的;

  • 栗子1:
    现在在一个浏览器的标签页里打开 http://www/knightboy.cn/a.html 页面,你通过location.href = http://baidu.com/b.html ,在同一个浏览器标签页里打开了不同域名下的页面,只要浏览器窗口相同,那么无论在哪个页面里访问都是一样的。

  • 栗子2:
    你的http://www.knightboy.cn/a.html 页面·里使用 调用另一个 http://baidu.com/b.html 页面,这时候你想在a页面里获取b页面里的DOM,然后进行操作,结果会发现不能获得b页面中的DOM。同样会因为不同源而报错,和上面提到的不同之处就是两个页面的一级域名也不相同,这时候 document.domain 即解决不了了。

浏览器窗口有 window.name 属性,这个属性的最大特点就是,无论是否同源,只要在同一个窗口里,前一个网页设置了这个属性,后一个网页可以读取它,比如当在 b 页面里设定 window.name = “hello” ,你再返回到 a 页面,在 a 页面访问 window.name ,可以得到 hello .这种方法的优点是,window.name 容量很大,可以放置非常长的字符串;缺点是必须监听子窗口 window.name 属性的变化,影响网页的性能。

方法四、document.domain
  • 可以将子域和主域的 document.domain 设置为同一个主域来实现跨越,但前提条件是,这两个域名必须属于同一个基础域名,所用的协议、端口都要一致,否则无法通过document.domain()来进行跨越。

  • 栗子1:
    如果想要在你的 http://www.knightboy.cn/a.html 页面里使用 调用另一个 http://knightboy.cn/b.html 页面里,这时候你想在a页面里面获取b 页面里的DOM,然后进行操作,然后就会发现你不能获得 b 的 DOM。document.getElementById(“myIFrame”).contentWindow.document或window.parent.document.body因为两个窗口不同源而报错。
    解决: 这时候你只需要在 a 页面里和 b 页面里把 document.doamin 设置成相同的值就可以在两个页面里操作DOM了;

  • 栗子2:
    如果你在 http://www.knightboy.cn/a.html 页面里写入 document.cookie = “text=hello”,而你再 http://www.knightboy.cn/a.html 页面里是拿不到cookie的。
    原因: cookie是服务器写入浏览器的一小段信息,只有同源的网页才能共享,但是,两个1页面一级域名,二级域名不同,浏览器允许通过设置 document.domain 来共享 cookie ,另外,服务器也可以在设置cookie的时候,指定cookie的所属域名为一级域名,这样的话,二级域名和三级域名不用做任何设置就可以读取cookie;
    注意: document.domain虽然可以读写,但只能设置为自身或者是高一级父域且主域必须相同,所以只能解决一级域名相同二级域名不相同的跨域问题,还有就是document.domain 只适用于 cookie 和 iframe 窗口,LocalStorage和IndexDB无法通过这种方法跨域。

方法五、片段识别符实现跨域

片段识别符就是指URL的**#**号后面的部分。比如,http://example.com/x.html#fragment的#fragment,如果只是改变片段标识符,页面不会重复刷新,父窗口和 iframe 的子窗口之间的通讯或者是 window.open 打开的子窗口之间的通讯。
父窗口跨域把信息,写入子窗口的片段标识符

var src= originURL + '#' + data;
document.getElementById('myIFrame').src = src;

子窗口通过监听hashange 事件得到通知

window.onhashchange = checkMessage;
function checkMessage() {
    var message = window.location.hash;
    //...  
}

同样,子窗口也可以改变父窗口的片段标识符。

parent.location.href = target + '#' + hash;

总之,父窗口改变子窗口的url的**#**号后面的部分,后者把要传递的参数写在 # 后面,子窗口监听 window.onhashchange 事件,得到通知后,读取window.location.hash 解析出有用的数据,同时子窗口也可以像父窗口传递数据。

请多多指教~!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值