当前位置:网站首页 > 编程语言 > 正文

跨域问题解决方案(跨域问题解决方案有哪些)



导语 | 在日常开发过程中,我们通常都会遇到ajax跨域请求或者前端跨域通信的开发场景。无论是前端同学还是后端同学都需要具备解决跨域问题的能力。本文总结梳理了常见的跨域场景、跨域解决方案及其优缺点,希望可以作为大家解决跨域问题的参考。

一、什么是跨域

当a..com域名下的页面或脚本试图去请求b..com域名下的资源时,就是典型的跨域行为。跨域的定义从受限范围可以分为两种,广义跨域和狭义跨域。

广义跨域通常包含以下三种行为:

其中,资源跳转和资源嵌入行为可以正常请求到跨域资源,脚本请求在未经任何处理的情况下,通常会有跨域问题。

同源策略(Same origin policy, SOP)是一种约定,由Netscape公司1995年引入浏览器,它是浏览器最核心也最基本的安全功能,如果缺少了同源策略,浏览器很容易受到XSS、CSFR等攻击。所谓同源策略是指“协议+域名+端口”三者相同。

狭义跨域正是浏览器同源策略限制的一类请求场景,即我们通常说的跨域行为,通常包含以下三种行为:

二、常见跨域场景

三、跨域解决方案

日常开发过程中,绝大多数前端页面都会向后端发送ajax请求进行数据交互。那么,ajax请求遇到跨域问题,如何进行解决呢。本文总结以下四种常见解决方案:

jsonp (JSON with Padding),是JSON的一种“使用模式”,可以让网页跨域读取数据。其本质是利用script标签的开放策略,浏览器传递callback参数到后端,后端返回数据时会将callback参数作为函数名来包裹数据,从而浏览器就可以跨域请求数据并定制函数来自动处理返回数据。

jsonp跨解实现流程:

jsonp跨域代码示例:

jsonp跨域优点

jsonp跨域缺点

跨域资源共享(Cross-origin resource sharing,CORS)是一个 W3C标准,允许浏览器向跨域服务器发送请求,从而克服了ajax只能同源使用的限制。CORS需要浏览器和服务器同时支持。目前,所有主流浏览器(IE10及以上)使用XMLHttpRequest对象都可支持该功能,IE8和IE9需要使用XDomainRequest对象进行兼容。

CORS整个通信过程都是浏览器自动完成,浏览器一旦发现ajax请求跨源,就会自动在头信息中增加Origin字段,用来说明本次请求来自哪个源(协议+域名+端口)。因此,实现CORS通信的关键是服务器,需要服务器配置Access-Control-Allow-Origin头信息。当CORS请求需要携带cookie时,需要服务端配置Access-Control-Allow-Credentials头信息,前端也需要设置withCredentials。

浏览器将CORS请求分成两类:简单请求和非简单请求。简单请求需要满足以下两大条件

CORS简单请求跨域实现流程:

CORS简单请求跨域代码示例:

CORS跨域优点

CORS跨域缺点:

由于IE7及以下浏览器默认是不兼容跨域请求的,那么在不改造后端的情况下,可以考虑使用Flash进行跨域请求。

Flash在进行跨域请求时,默认首先会发送预检请求,检查服务器域名根目录下的crossdomain.xml文件,判断请求域是否合法。如果域名不合法,Flash直接封杀请求;如果域名合法,则发送真实请求,获取数据并返回给前端页面。

corssdomain.xml是目标域下的主策略文件,其文件配置规则如下:

(1)cross-domain-policy

crossdomain.xml的根元素,包含以下子元素:

(2)site-control

是否允许加载其他策略文件,属性值permitted-cross-domain-policies允许的值有:

(3)allow-access-from

用于授权数据访问的请求域,具有以下属性:

(4)allow-access-from-identity

允许有特定证书的请求域跨域访问目标域上的资源。

(5)allow-http-request-headers-from

用于授权发送用户定义HTTP头的请求域,具有以下属性:

crossdomain.xml文件配置示例:

Flash跨域实现流程:

Flash跨域代码示例:

Flash跨域优点

Flash跨域缺点

服务器代理,顾名思义即在发送跨域请求时,后端进行代理中转请求至服务器端,然后将获取的数据返回给前端。一般适用于以下场景:

针对IE7及以下浏览器摒弃Flash插件的情况,配置代理接口与前端页面同源,并中转目标服务器接口,则ajax请求不存在跨域问题。

外网前端页面无法访问内网接口,配置代理接口允许前端页面访问,并中转内网接口,则外网前端页面可以跨域访问内网接口。

服务器代理实现流程:

服务器代理优点

服务器代理缺点

前端跨域通信是指浏览器中两个不符合同源策略的前端页面进行通信。那么,这种跨域问题,如何进行解决呢。本文总结以下四种常见解决方案:

此方案仅适用于主域相同,子域不同的前端通信跨域场景。如下图所示,两个不符合同源策略的页面http://a..com/a.html和http://b..com/b.html,其主域相同为.com。a.html嵌套b.html,再都通过js设置document.domain为主域.com,则两个页面满足了同源策略,从而实现了跨域通信。

document.domain+iframe方案代码示例:

document.domain+iframe方案优点

document.domain+iframe方案缺点

当两个不符合同源策略且主域不同的页面需要进行跨域通信时,可以利用url的hash值改变但不刷新页面的特性,实现简单的前端跨域通信。

通常情况下http://a..com/a.html内嵌不同域的http://b.1.com/b.html时,受浏览器安全机制限制,a.html 可以修改b.html的hash值,但b.html不被允许修改不同域的父窗体a.html的hash值。因此,此方案需要一个与a.html同源的http://a..com/c.html来进行中转,此方案实现流程如下图所示:

location.hash+iframe方案代码示例:

location.hash+iframe方案优点

location.hash+iframe方案缺点

window.name属性的独特之处在于,name值在不同页面(甚至不同域名)加载后依旧存在,并且可以支持非常长的name值(2MB)。

如下图所示,http://a..com/a.html内嵌不同域的http://b.1.com/b.html。b.html有数据要传递时,把数据附加到window.name上,然后跳转到一个和a.html同域的http://a..com/c.html。由于a.html和c.html满足同源策略,a.html可以获取c.html的window.name,从而实现了跨域通信。

window.name+iframe代码示例:

window.name+iframe方案优点

window.name+iframe方案缺点

postMessage是HTML5 XMLHttpRequest Level2中的API,且是为数不多可以跨域操作的window属性之一,它通常用于解决以下方面的问题:

postMessage是一种安全的跨域通信方法。当a.html获得对b.html的window对象后,a.html调用postMessage方法分发一个MessageEvent消息。b.html通过监听message事件即可获取a.html传递的数据,从而实现跨域通信。postMessage实现流程如下图所示:

postMessage方法的语法如下:

otherWindow.postMessage(message、targetOrigin、[transfer])

目标窗口的window对象,比如iframe的contentWindow属性、执行window.open返回的window对象等。

将要发送给其他window的数据。

指定哪些窗口能接收到消息事件,其值可以是字符串*(表示无限制)或者是“协议+主机+端口号”。

是一串和message同时传递的Transferable对象,这些对象的所有权将被转移给消息的接收方,而发送一方将不再保有所有权。

postMessage方案代码示例:

postMessage方案优点

postMessage方案缺点

四、总结

本文介绍了浏览器受同源策略限制的跨域行为以及常见的跨域场景。总结了跨域问题的经验,并从ajax请求和前端通信两大方向进行梳理常用的跨域解决方法及其优缺点,希望可以作为大家在日常开发解决web跨域问题的参考。如果有描述不当之处,也希望大家随时进行沟通和指正。

参考资料: 1.浏览器的同源策略

2.跨源资源共享(CORS)

3.Cross-domain AJAX using Flash

4.window.postMessage

 作者简介

刘孟

腾讯前端开发工程师

腾讯前端开发工程师,毕业于上海大学。目前负责腾讯优联项目的前端开发工作,有丰富的系统平台及游戏营销活动前端开发经验。

 推荐阅读

到此这篇跨域问题解决方案(跨域问题解决方案有哪些)的文章就介绍到这了,更多相关内容请继续浏览下面的相关推荐文章,希望大家都能在编程的领域有一番成就!

版权声明


相关文章:

  • 网页传输文件怎么弄(网页传输文件怎么弄的)2025-05-14 16:00:07
  • u盘制作pe系统启动盘后还能用吗(u盘制作成pe盘后还能还原吗)2025-05-14 16:00:07
  • yum命令(安装yum命令)2025-05-14 16:00:07
  • jflash读取程序(jflash下载程序步骤)2025-05-14 16:00:07
  • wifi字典爆破手机(字典爆破wifi密码)2025-05-14 16:00:07
  • ad20怎么添加库文件(ad中如何添加库文件)2025-05-14 16:00:07
  • ip与域名是一一对应吗(ip地址和域名是一一对应的关系吗)2025-05-14 16:00:07
  • 圈1到圈10怎么打快捷键(键盘上怎么打圈1圈2啊)2025-05-14 16:00:07
  • 发送验证码手机收不到验证码是什么原因(发送验证码收不到短信是怎么回事)2025-05-14 16:00:07
  • ew是什么意思的缩写(ew是什么意思英语)2025-05-14 16:00:07
  • 全屏图片