您当前的位置:首页 > 电脑百科 > 网络技术 > 网络知识

一文搞懂跨域的所有问题

时间:2019-09-02 15:56:40  来源:  作者:

本文原作者: Wizey,作者博客:http://wenshixin.gitee.io,即时通讯网收录时有改动,感谢原作者的无私分享。

1、引言

典型的Web端即时通讯技术应用场景,主要有以下两种形式:

  • 1)作为完整的即时通讯产品进行应用:比如独立的Web端IM产品;2)作为某个更大系统中的一部分进行应用:比如客服系统(相当于工单系统里嵌入IM技术啦)。

对于第一种场景,为了更好的划分功能逻辑,一个完整的产品通常都会调用来自于不同服务器提供的各种接口(比如各种服务端微服务接口),那么Web端跨域问题就无法回避了。

对于第二种场景,就更好理解:为了提升系统的可维护性,不同子系统间代码的互不倾入、低偶合设计,导致im子系统或服务很可能部署于独立的一台或多台服务器(域名)上,那么跨域问题显而易见。

所以,对于Web端即时通讯开发者来说,跨域问题是必须掌握的知识范畴。本文将为你讲解跨域问题原理,以及理论联系实际,用实践代码也为你演示解决跨域问题的几种方法。

PS:虽然在开发Web端即时通讯应用时,普通的Ajax调用、iframe文件上传等存在跨域问题,但好消息是作为技术核心的 WebSocket 技术是支持跨域的(不存在跨域问题)!

友情提示:本文配套的实践代码,请从文末附件处下载!

Web端即时通讯基础知识补课:一文搞懂跨域的所有问题

 

(本文同步发布于:http://www.52im.net/thread-2732-1-1.html

2、什么是跨域问题

前端调用的后端接口不属于同一个域(域名或端口不同),就会产生跨域问题,也就是说你的应用访问了该应用域名或端口之外的域名或端口。

Web端即时通讯基础知识补课:一文搞懂跨域的所有问题

 

通俗的讲,跨域问题是因为浏览器的同源策略规定某域下的客户端在没明确授权的情况下,不能读写另一个域的资源。而在实际开发中,前后端常常是相互分离的,并且前后端的项目部署也常常不在一个服务器内或者在一个服务器的不同端口下。前端想要获取后端的数据,就必须发起请求,如果不做一些处理,就会受到浏览器同源策略的约束。后端可以收到请求并返回数据,但是前端无法收到数据。

3、为什么会发生跨域问题

要同时满足三个条件才会产生跨域问题:

  • 1)浏览器限制,而不是服务端限制,可以查看Network,请求能够正确响应,response返回的值也是正确的;2)请求地址的域名或端口和当前访问的域名或端口不一样;3)发送的是XHR(XMLHttpRequest)请求,可以使用 a 标签(模拟xhr请求)和 img 标签(模拟json请求)做对比(控制台只报了一个跨域异常)。
Web端即时通讯基础知识补课:一文搞懂跨域的所有问题

 

关于 XMLHTTPRequest 可以参看这篇文章 :《你真的会使用XMLHttpRequest吗?》。

跨域问题的根本,就是浏览器制定的同源策略导致的。

浏览器制定同源策略,其中一个重要原因就是对cookie的保护。

cookie 中存着sessionID 。黑客一旦获取了sessionID,并且在有效期内,就可以登录。当我们访问了一个恶意网站 如果没有同源策略 那么这个网站就能通过js 访问document.cookie 得到用户关于的各个网站的sessionID 其中可能有银行网站 等等。通过已经建立好的session连接进行攻击,比如CSRF攻击。

这里需要服务端配合再举个例子,现在我扮演坏人 我通过一个iframe 加载某宝的登录页面 等傻傻的用户登录我的网站的时候 我就把这个页面弹出用户一看 阿里唉大公司 肯定安全 就屁颠屁颠的输入了密码 注意 如果没有同源策略 我这个恶意网站就能通过dom操作获取到用户输入的值 从而控制该账户所以同源策略是绝对必要的。

还有需要注意的是同源策略无法完全防御CSRF(即(Cross-site request forgery)跨站请求伪造)。

4、解决跨域问题的三种思路

  • 1)客户端浏览器解除跨域限制:此方式理论上可以但是不现实;2)发送JSONP请求替代XHR请求:此种方式虽然有一定的局限性——比如请求只能是GET方式,但对于部署来说很友好,因为不需要修改服务器配置;3)修改服务器端配置(包括HTTP服务器和应用服务器):此方式对于GET、POST请求来说,没有局限性,但对于部署来说不太友好,需要修改应用服务器、反向代理服务器的相关配置。

5、跨域问题解决方法1:设置浏览器解除跨域限制

浏览器默认都是开启跨域安全检查的,我们可以使用命令行启动浏览器,加上禁止安全检查的参数,以谷歌浏览器为例,chrome.exe --disable-web-security --user-data-dir=E:/temp --user-data-dir 为浏览器缓存临时目录,浏览器这时会提示安全问题。

Web端即时通讯基础知识补课:一文搞懂跨域的所有问题

 

【浏览器如何判断一个请求是不是跨域请求?】

浏览器会根据同源策略来判断一个请求是不是跨域请求。

非跨域请求:在请求头中会只包含请求的主机名:

Web端即时通讯基础知识补课:一文搞懂跨域的所有问题

 

跨域请求:在请求头中会既包含要请求的主机名还包括当前的源主机名,如果这两者不一致,那就是跨域请求了:

Web端即时通讯基础知识补课:一文搞懂跨域的所有问题

 

【浏览器对请求的分类】

在HTTP1.1 协议中的,请求方法分为GET、POST、PUT、DELETE、HEAD、TRACE、OPTIONS、CONNECT 八种。浏览器根据这些请求方法和请求类型将请求划分为简单请求和非简单请求。

简单请求:浏览器先发送(执行)请求然后再判断是否跨域。

请求方法为 GET、POST、HEAD,请求头header中无自定义的请求头信息,请求类型Content-Type 为 text/plain、multipart/form-data、Application/x-www-form-urlencoded 的请求都是简单请求。

非简单请求:浏览器先发送预检命令(OPTIONS方法),检查通过后才发送真正的数据请求。

Web端即时通讯基础知识补课:一文搞懂跨域的所有问题

 

预检命令会发送自定义请求头为Access-Control-Request-Headers: content-type的请求到服务器,根据响应头的中的 “Access-Control-Allow-Headers”: “Content-Type” 判断服务器是否允许跨域访问。预检命令是可以缓存,服务器端设置 “Access-Control-Max-Age”: “3600”,这样后面发送同样的跨域请求就不需要先发送预检命令了。

请求头的含义如下所示:

Web端即时通讯基础知识补课:一文搞懂跨域的所有问题

 

响应头的含义如下所示:

Web端即时通讯基础知识补课:一文搞懂跨域的所有问题

 

请求方法为 PUT、DELETE 的 AJAX 请求、发送 JSON 格式的 AJAX 请求、带自定义头的 AJAX 请求都是非简单请求。

6、跨域问题解决方法2:使用JSONP替代XHR

6.1 JSONP 是什么

JSONP(JSON with Padding)是JSON的一种补充使用方式,不是官方协议,而是利用 Script 标签请求资源可以跨域的特点,来解决跨域问题的,是一种变通的解决方案。(详见《详解Web端通信方式的演进:从Ajax、JSONP 到 SSE、Websocke》一文中的第3节“三、JSONP”)

6.2 使用 JSONP,服务器后台代码需要改动吗?

答案是需要,这里以Spring Boot为例,在 Spring Boot 1.5 大版本中,添加一个切面来支持JSONP请求。

AJAX代码如下:
$.ajax({
 url: baseUrl + "/get1",
 dataType: "jsonp", // 关键字段
 jsonp: "callback", // 前后端默认的约定
 cache: true, // 表示请求结果可以被缓存,url中不会有下划线参数了
 success: function(json) {
 result = json;
 }
}); 
服务端代码:
@ControllerAdvice
public class JsonpAdvice extends AbstractJsonpResponseBodyAdvice {
 public JsonpAdvice() {
 super("callback");
 }
}

6.3 JSONP 实现原理

JSONP请求的类型是JAVAScript脚本(callback 作为前后端的约定,callback的值做为方法名,json内容作为方法的参数),而XHR请求的类型是json类型。

Web端即时通讯基础知识补课:一文搞懂跨域的所有问题

 

▲ JSONP返回类型和XHR返回类型对比

可以在浏览器中查看 Jquery 源码来验证 JSONP 是否将请求包装成了 script 脚本。

Web端即时通讯基础知识补课:一文搞懂跨域的所有问题

 

▲ JSONP动态生成script标签

在 Jquery 源码中打断点。

Web端即时通讯基础知识补课:一文搞懂跨域的所有问题

 

▲ 在jquery中打断点

刷新后查看 element 元素,可以看到 Jquery 在 html 源码中添加了 script 标签。

Web端即时通讯基础知识补课:一文搞懂跨域的所有问题

 

▲ jquery动态生成script脚本

6.4 JSONP的优缺点

JSONP的优点:部署时不需要应用服务器去进行额外的配置,跟普通的非跨域系统部署一模一样,没有特别的要求。

JSONP的缺点:

  • 1)只支持 GET 方法请求,不管 AJAX 中实际的请求方法是不是 GET;2)服务端还需要修改代码(如果你认为修改服务端代码比修改服务器的配置相比,很烦的话,这倒是可以算作是缺点);3)发送的不是 XHR 请求,无法使用 XHR 对象(但这也是为什么可以解决跨域问题的根本)。

7、跨域问题解决方法3:修改应用服务器的跨域配置

根据现如今网站架构设计,可以将前端应用看作调用方使用服务,将后端应用看作被调用方提供服务。

Web端即时通讯基础知识补课:一文搞懂跨域的所有问题

 

根据服务器的作用,可以将服务器分为 HTTP 服务器和应用服务器,所有修改服务器端既可以是修改应用服务器,也可以是修改 HTTP 服务器。

7.1 被调用方修改

被调用方的解决思路是在响应头中增加指定的字段允许调用方服务器跨域调用。

Web端即时通讯基础知识补课:一文搞懂跨域的所有问题

 

在应用服务器增加指定字段:

对于不带 Cookie 的跨域请求,设置允许跨域的原始域名为任意域名,”Access-Control-Allow-Origin”: “*“,设置允许跨域的方法为任意方法,”Access-Control-Allow-Methods”: “*“,但是这样的星号设置不能满足带 Cookie 的跨域请求。

Web端即时通讯基础知识补课:一文搞懂跨域的所有问题

 

对于带 Cookie 的跨域请求,要指名允许跨域请求的调用方主机名,Cookie 要加在调用方。

带自定义头的跨域请求,设置允许跨域的请求头自定义的请求头,”Access-Control-Allow-Headers”:”自定义的请求头”。

在 Java Web 中,可以添加一个过滤器来设置上面的参数。

Web端即时通讯基础知识补课:一文搞懂跨域的所有问题

 

▲ 被调用方使用Filter解决跨域

而使用 Spring Boot 框架,只需要在 Controller 类上加上 @CrossOrigin 注解就可以轻松解决跨域问题了。

在 HTTP 服务器增加指定字段:

以常用的 Nginx 服务器和 Apache 服务器为例。

Nginx 服务器允许跨域配置(注意不要手动直接点击Nginx.exe,否则停止和重新载入配置会失败的):

Web端即时通讯基础知识补课:一文搞懂跨域的所有问题

 

Apache 服务器允许跨域配置:

Web端即时通讯基础知识补课:一文搞懂跨域的所有问题

 

7.2 调用方修改

调用方的解决思路是反向代理,也即是将被调用方的域名代理到调用方域名下,这样就符合同源策略了,也就解决了跨域问题。

Web端即时通讯基础知识补课:一文搞懂跨域的所有问题

 

▲ 调用方反向代理效果演示

调用方修改一般都是直接修改 HTTP 服务器配置。

Nginx 服务器反向代理配置:

Web端即时通讯基础知识补课:一文搞懂跨域的所有问题

 

Apache 服务器反向代理配置:

Web端即时通讯基础知识补课:一文搞懂跨域的所有问题

 

8、本文配套的代码下载

请从链接:Web端即时通讯基础知识补课:一文搞懂跨域的所有问题!-网页端IM开发/专项技术区 - 即时通讯开发者社区! 末尾处附件中下载之。

附录1:Web端即时通讯技术入门文章提纲

Web即时通讯新手入门贴:

《新手入门贴:详解Web端即时通讯技术的原理》

Web端即时通讯技术盘点请参见:

《Web端即时通讯技术盘点:短轮询、Comet、Websocket、SSE》

关于Ajax短轮询:

找这方面的资料没什么意义,除非忽悠客户,否则请考虑其它3种方案即可。

有关Comet技术的详细介绍请参见:

《Comet技术详解:基于HTTP长连接的Web端实时通信技术》

《WEB端即时通讯:HTTP长连接、长轮询(long polling)详解》

《WEB端即时通讯:不用WebSocket也一样能搞定消息的即时性》

《开源Comet服务器iComet:支持百万并发的Web端即时通讯方案》

更多WebSocket的详细介绍请参见:

《新手快速入门:WebSocket简明教程》

《WebSocket详解(一):初步认识WebSocket技术》

《WebSocket详解(二):技术原理、代码演示和应用案例》

《WebSocket详解(三):深入WebSocket通信协议细节》

《WebSocket详解(四):刨根问底HTTP与WebSocket的关系(上篇)》

《WebSocket详解(五):刨根问底HTTP与WebSocket的关系(下篇)》

《WebSocket详解(六):刨根问底WebSocket与Socket的关系》

《理论联系实际:从零理解WebSocket的通信原理、协议格式、安全性》

《Socket.IO介绍:支持WebSocket、用于WEB端的即时通讯的框架》

《socket.io和websocket 之间是什么关系?有什么区别?》

有关SSE的详细介绍文章请参见:

《SSE技术详解:一种全新的HTML5服务器推送事件技术》

更多WEB即时通讯文章请见:

http://www.52im.net/forum.php?mod=collection&action=view&ctid=15

附录2:更多有关WEB端即时通讯开发的精华文章

《Web端即时通讯技术盘点:短轮询、Comet、Websocket、SSE》

《SSE技术详解:一种全新的HTML5服务器推送事件技术》

《socket.io实现消息推送的一点实践及思路》

《LinkedIn的Web端即时通讯实践:实现单机几十万条长连接》

《Web端即时通讯技术的发展与WebSocket、Socket.io的技术实践》

《Web端即时通讯安全:跨站点WebSocket劫持漏洞详解(含示例代码)》

《开源框架Pomelo实践:搭建Web端高性能分布式IM聊天服务器》

《使用WebSocket和SSE技术实现Web端消息推送》

《详解Web端通信方式的演进:从Ajax、JSONP 到 SSE、Websocket》

《MobileIMSDK-Web的网络层框架为何使用的是Socket.io而不是Netty?》

《理论联系实际:从零理解WebSocket的通信原理、协议格式、安全性》

微信小程序中如何使用WebSocket实现长连接(含完整源码)》

《八问WebSocket协议:为你快速解答WebSocket热门疑问》

《快速了解Electron:新一代基于Web的跨平台桌面技术》

《一文读懂前端技术演进:盘点Web前端20年的技术变迁史》

《Web端即时通讯知识补课:一文搞懂跨域的所有问题!》

>>更多同类文章 ……

(本文同步发布于:http://www.52im.net/thread-2732-1-1.html)



Tags:跨域   点击:()  评论:()
声明:本站部分内容及图片来自互联网,转载是出于传递更多信息之目的,内容观点仅代表作者本人,如有任何标注错误或版权侵犯请与我们联系(Email:2595517585@qq.com),我们将及时更正、删除,谢谢。
▌相关推荐
问题后端已经配置好了跨域,前端本地搭建vue-cli测试环境的时候如何解决跨域?(前提进行了基本的axios封装)分析这个时候后端API是一个明确的外网环境(使用外网IP或固定域名访问),...【详细内容】
2021-11-03  Tags: 跨域  点击:(55)  评论:(0)  加入收藏
浏览器的同源策略跨域的根本原因就是因为浏览器的同源策略,这是浏览器出于安全性考虑做出的限制,所谓同源是指:域名、协议、端口相同。比如在互联网上有两个资源(网页或者请求等...【详细内容】
2021-09-17  Tags: 跨域  点击:(101)  评论:(0)  加入收藏
前言难以置信,我居然被跨域问题折磨了一上午。相信很多程序员都遇到过跨域问题,当然,解决方案也有很多种。但我今天尝试了无数种办法,依旧没有解决。直到最后我媳妇儿给了我个提...【详细内容】
2021-09-16  Tags: 跨域  点击:(108)  评论:(0)  加入收藏
“前端如何解决跨域问题?” 这个是前段在知乎看到的一个提问,这几乎是做前端都会遇到的一个问题,产生的情况可能会很多,解决一个问题还是要先了解下为什么会产生这样问题,学习最好的方法就是结合一些实际的案例来学习,理解...【详细内容】
2021-06-09  Tags: 跨域  点击:(171)  评论:(0)  加入收藏
首先说一下,跨域它不是一个问题,它是浏览器的一种安全策略,叫同源策略。拿前后端分离项目来说,前端调试或者部署的地址,与api的地址,必须拥有相同的协议、域名、端口号。否则,前端...【详细内容】
2021-02-19  Tags: 跨域  点击:(264)  评论:(0)  加入收藏
什么是CSRF攻击?了解CSRF攻击的最佳方法是看一个具体示例。 例子假设您银行的网站提供了一种表格,该表格允许将资金从当前登录的用户转移到另一个银行帐户。例如,转账表单可能...【详细内容】
2021-01-15  Tags: 跨域  点击:(154)  评论:(0)  加入收藏
1、背景随着MPLS技术的成熟,其应用越来越广泛,尤其是在VPN方面。电信运营商提供给用户的MPLSVPN服务主要有MPLSLayer2 VPN和 MPLS Layer 3 VPN两类。MPLS Layer 2 VPN因标准化...【详细内容】
2021-01-04  Tags: 跨域  点击:(160)  评论:(0)  加入收藏
这篇文章我们聊一聊CORS跨域,它的全称是"跨域资源共享"(Cross-origin resource sharing)。在之前的文章中我们已经详细介绍了如何使用JSONP进行接口跨域请求,如果不了解的可以参...【详细内容】
2020-12-28  Tags: 跨域  点击:(165)  评论:(0)  加入收藏
内容简介MPLS VPN跨域互联有三种方式,分别是Option-A、Option-B、Option-C。这三种方式各自有各自的优缺点,你不能说某种跨域方式就能完全替代另外一种。但有时候,遇到两个ASBR...【详细内容】
2020-12-15  Tags: 跨域  点击:(307)  评论:(0)  加入收藏
前言:Axios是一个来自于vue官方推荐的一个用于与后端(Java、go、Python、PHP)进行数据交互的JavaScript库,你可以通过axios库快速高效的与后端进行数据交互,是现文件上传等复杂功...【详细内容】
2020-10-09  Tags: 跨域  点击:(163)  评论:(0)  加入收藏
▌简易百科推荐
以京训钉开发平台接口文档为例,使用HttpClient类请求调用其接口,对数据进行增删改查等操作。 文档地址: https://www.yuque.com/bjjnts/jxd/bo1oszusing System;using System.C...【详细内容】
2021-12-28  Wednes    Tags:HttpClient   点击:(1)  评论:(0)  加入收藏
阿里云与爱快路由安装组网教程一、开通好阿里云轻量服务器之后在服务器运维-远程连接处进行远程 二、进入控制台后在root权限下根据需要安装的固件位数复制下面命令。32位:wg...【详细内容】
2021-12-28  ikuai    Tags:组网   点击:(1)  评论:(0)  加入收藏
HTTP 报文是在应用程序之间发送的数据块,这些数据块将通过以文本形式的元信息开头,用于 HTTP 协议交互。请求端(客户端)的 HTTP 报文叫做请求报文,响应端(服务器端)的叫做响应...【详细内容】
2021-12-27  程序员蛋蛋    Tags:HTTP 报文   点击:(5)  评论:(0)  加入收藏
一 网络概念:1.带宽: 标识网卡的最大传输速率,单位为 b/s,比如 1Gbps,10Gbps,相当于马路多宽2.吞吐量: 单位时间内传输数据量大小单位为 b/s 或 B/s ,吞吐量/带宽,就是网络的使用率...【详细内容】
2021-12-27  码农世界    Tags:网络   点击:(3)  评论:(0)  加入收藏
1.TCP/IP 网络模型有几层?分别有什么用? TCP/IP网络模型总共有五层 1.应用层:我们能接触到的就是应用层了,手机,电脑这些这些设备都属于应用层。 2.传输层:就是为应用层提供网络...【详细内容】
2021-12-22  憨猪哥08    Tags:TCP/IP   点击:(35)  评论:(0)  加入收藏
TCP握手的时候维护的队列 半连接队列(SYN队列) 全连接队列(accepted队列)半连接队列是什么?服务器收到客户端SYN数据包后,Linux内核会把该连接存储到半连接队列中,并响应SYN+ACK报...【详细内容】
2021-12-21  DifferentJava    Tags:TCP   点击:(10)  评论:(0)  加入收藏
你好,这里是科技前哨。 随着“元宇宙”概念的爆火,下一代互联网即将到来,也成了互联网前沿热议的话题,12月9日美国众议院的听证会上,共和党议员Patrick McHenry甚至宣称,要调整现...【详细内容】
2021-12-17  王煜全    Tags:Web3   点击:(14)  评论:(0)  加入收藏
一、demopublic static void main(String[] args) throws Exception { RetryPolicy retryPolicy = new ExponentialBackoffRetry( 1000, 3);...【详细内容】
2021-12-15  程序员阿龙    Tags:Curator   点击:(22)  评论:(0)  加入收藏
一、计算机网络概述 1.1 计算机网络的分类按照网络的作用范围:广域网(WAN)、城域网(MAN)、局域网(LAN);按照网络使用者:公用网络、专用网络。1.2 计算机网络的层次结构 TCP/IP四层模...【详细内容】
2021-12-14  一口Linux    Tags:网络知识   点击:(31)  评论:(0)  加入收藏
无论是在外面还是在家里,许多人都习惯了用手机连接 WiFi 进行上网。不知道大家有没有遇到过这样一种情况, 明明已经显示成功连接 WiFi,却仍然提示“网络不可用”或“不可上网”...【详细内容】
2021-12-14  UGREEN绿联    Tags:WiFi   点击:(25)  评论:(0)  加入收藏
最新更新
栏目热门
栏目头条