前端基础 | 浅谈前端跨域

本文主要探讨了前端开发中的跨域问题,包括同源策略、Cookie跨子域共享、iframe窗口通信的各种方式,如document.domain、window.name、location.hash以及window.postMessage。此外,还详细介绍了AJAX跨域的JSONP和CORS实现。通过实例讲解了如何在不同场景下实现跨域通信,是前端开发者理解跨域问题的良好参考资料。

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

@author YogaZheng

鉴于本人目前正处于前端基础知识学习阶段,本文仅是在阅读了网络上诸多相关文章后的一个总结,加上一点自己写的小例子,更多的是用于自己的个人积累。看到这篇文章的朋友,我更建议大家去阅读本文参考资料中的文章(均附有链接),可以对跨域问题有更深刻的理解。

目录

同源与跨域

同源

同源策略

跨域

Cookie跨子域共享

iframe跨域窗口通信

document.domain

window.name(完整例子见附一)

location.hash

window.postMessage

AJAX跨域实现

JSONP

CORS

参考资料

附一:document.name在跨域中的应用举例


同源与跨域

同源

如果两个页面协议相同、域名相同、端口相同,则称这两个页面同源。相反的,如果两个页面的协议、域名、端口中有一个或多个不同,则称这两个页面非同源。

对于网址http://www.cityworks.cn:80而言,http://是协议,www.cityworks.cn是域名,80是端口(默认端口通常省略)。对于这个网址,其同源情况如下:

  • http://www,cityworks,cn/pages/newsInfo,html 同源,协议、域名、端口均相同

  • https://www.cityworks.cn:80 不同源,协议不同

  • http://www.yuque.com 不同源,域名不同

  • http://www.cityworks.cn:2333 不同源,端口不同

同源策略

简单来说,同源策略是限制了两个源之间资源交互的一种浏览器安全机制。对于非同源网页/网站,会受到三种行为限制:

  • 无法读取对方的Cookies、LocalStorage、IndexDB

  • 无法获得对方的DOM

  • 无法向对方发送AJAX请求

同源策略的制定是出于网络安全性考虑,防止恶意窃取数据,隔离潜在恶意文件。设想以下两种情景:

  • 你打开了银行账户页面,然后又"不小心"打开了一个恶意网站,如果没有同源策略,此时该恶意网站就可以通过javascript脚本"随心所欲地"访问、窃取、修改你的银行信息,包括账号密码。

  • 当你使用Cookie来维护用户的登录状态时(这也是我们现在经常做的),如果没有同源策略,这些Cookie信息就会泄露,其他网站就可以冒充这个登录用户。

跨域

如果两个页面非同源,我们试图进行这两个页面通信的行为称为跨域。

这里值得一提的是,跨域并非是浏览器限制了发起跨域请求,而是跨站请求可以正常发起,但返回结果被浏览器拦截了。也有特例,比如Chrome和Firefox浏览器对于从HTTPS协议访问HTTP协议的跨域请求在其未发出时就拦截。

在实际的项目开发过程中,我们总会不可避免的要进行跨域请求操作。但是,对于协议和端口不同的跨域问题,前端是无法解决的,需要通过后台实现。 所以通常而言,前端所说的跨域处理指的是对于不同域名通信的跨域实现,也就是本文讨论的主要内容。

 

Cookie跨子域共享

我们知道,由于同源策略的限制,Cookie只有同源的页面才能共享。但是,如果两个页面主域名相同,子域名不同,浏览器允许通过设置docuement.domain共享Cookie和DOM。

举个栗子,A页面地址是http://a.example.com/a.html,B页面地址是http://b.example.com/b.html,那么只要两个页面将各自的document.domain指向同一主域example.com,它们就可以共享Cookie。

在A页面设置document.domain,并通过脚本设置一个Cookie:

document.domain = 'example.com';
document.cookie = 'favourite_food=chocolate';

在B页面设置相同的document.domain,就可以读取到这个Cookie:

document.domain = 'example.com';
console.log(document.cookie); //包括'favourite_food=chocolate'

另外,服务器也可以在设置Cookies的时候,指定Cookies的所属域名为主域名:

Set-Cookie: key=value; domain=.example.com; path=/

如此,二级、三级域名不用做任何设置,就都可以读取这个Cookie。

 

iframe跨域窗口通信

项目中会有使用iframe把其他域名的内容嵌入页面中的场景(比如登录/注册等表单提交浮窗),有时候会需要与父窗口进行通信。

document.domain

如果打开窗口的主域与父窗口主域相同,子域名不同,那么同Cookie一样,可以使用document.domain进行通信,获取彼此的DOM。

举个栗子:在A页面http://a.example.com/a.html中有一个<iframe>标签,它的src属性的值是http://b.example.com/b.html,对应B页面,它们有共同的主域example.com,那么只要两个页面将document.domain设置为这一主域,就可以相互访问DOM。

父窗口a.html:

<iframe id="iframe" src="http://b.example.com/b.html"></iframe>
<ul id="arms">
    <li>陈情</li>
    <li>避尘</li>
</ul>
<script type="text/javascript">
    document.domain = 'example.com';
    window.onload = function() {
        var iframe = document.getElementBtId('iframe');
        var childDoc = iframe.contentWindow.document;
        console.log(doc.getElementById('cp')); // 魏无羡 蓝忘机
    }
</script>

子窗口b.html:

<ul id="cp">
    <li>魏无羡</li>
    <li>蓝忘机</li>
</ul>
<script type="text/javascript">
    var parentDoc = window.parent.document;
    console.log(doc.getElementById('arms')); // 陈情 避尘
</script>

window.name(完整例子见附一)

window.name有一个特征:在一个窗口(window

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值