SpringBoot教程(七) | SpringBoot解决跨域问题

SpringBoot教程(七) | SpringBoot解决跨域问题

上篇文章我们介绍了SpringBoot的拦截器的写法,其中有一个比较重要的步骤,就是把我们写好的拦截器注册到Spring的一个配置类中,这个类是实现了WebMvcConfigurer 接口,这个类很重要,因为这个类中除了可以注册拦截以外,还可以配置很多内容。今天我们来讲解一下SpringBoot如何解决跨域问题。 先来解释一下什么是跨域问题。

7.1 什么是跨域?

当一个请求url的协议、域名、端口三者之间任意一个与当前页面url不同即为跨域

image.png

7.2 为什么会出现跨域

出于浏览器的同源策略限制。同源策略(Sameoriginpolicy)是一种约定,它是浏览器最核心也最基本的安全功能,如果缺少了同源策略,则浏览器的正常功能可能都会受到影响。可以说Web是构建在同源策略基础之上的,浏览器只是针对同源策略的一种实现。同源策略会阻止一个域的javascript脚本和另外一个域的内容进行交互。所谓同源(即指在同一个域)就是两个页面具有相同的协议(protocol),主机(host)和端口号(port)

但是以前的程序为什么没有过跨域问题的困扰呢。那是因为以前的程序都不是前后端分离的。比如之前的jsp, freemarker实现的前端,他们和后端的代码都是放到一起的,所以他们一起部署,具有相同的域名,协议和端口号,自然不存在跨域的问题。

但是现在的程序都是前后端分离的程序,前后端分离的程序有什么特点,就是前后端都是单独部署的,前端服务和后端服务都会监听属于自己的端口号,所有很容易产生跨域的问题。当前端端不同源的时候,而前端的服务又需要去访问和他不同源的后端的接口,自然就产生了跨域的问题,所以在前后端分离的项目中,跨域问题是我们永远都绕不开的。

7.3 如何解决?

既然已经阐述了跨域问题,那我们应该如何解决呢?其实解决的方案还是不少的,我们列举几种常见的方法。

1. JSONP:

JSONP 是服务器与客户端跨源通信的常用方法。最大特点就是简单适用,兼容性好(兼容低版本IE),缺点是只支持get请求,不支持post请求。

核心思想:网页通过添加一个

这种方式是前端的实现,其实和后端关系不大。并且用的也不多。

2. Nginx 反向代理

使用 nginx 反向代理实现跨域,是最简单的跨域方式。只需要修改 nginx 的配置即可解决跨域问题,支持所有浏览器,支持 session,不需要修改任何代码,并且不会影响服务器性能。

我们只需要配置nginx,在一个服务器上配置多个前缀来转发http/https请求到多个真实的服务器即可。这样,这个服务器上所有url都是相同的域 名、协议和端口。因此,对于浏览器来说,这些url都是同源的,没有跨域限制。而实际上,这些url实际上由物理服务器提供服务。这些服务器内的 javascript可以跨域调用所有这些服务器上的url。

3. webpack本地代理

这个也是前端的一种实现,通过webpack技术,就可以将服务端进行反向代理,相当于前端模拟了nginx的功能,将后端的接口反代成一个同源的地址

4. CORS

CORS 是跨域资源分享(Cross-Origin Resource Sharing)的缩写。它是 W3C 标准,属于跨源 AJAX 请求的根本解决方法。

1、普通跨域请求:只需服务器端设置Access-Control-Allow-Origin

2、带cookie跨域请求:前后端都需要进行设置

服务器端对于CORS的支持,主要是通过设置Access-Control-Allow-Origin来进行的。如果浏览器检测到相应的设置,就可以允许Ajax进行跨域的访问。

我们重点讲解下springBoot如何通过设置CORS 来解决跨域问题。

7.4 解决方案

解决方案很简单,其实就是利用了我们昨天拦截器用到的那个配置类,在里面加一些代码即可。

java复制代码@Configuration
public class WebMvcConfig implements WebMvcConfigurer {// 昨天的拦截器注册@Overridepublic void addInterceptors(InterceptorRegistry registry) {//拦截registry.addInterceptor(new TokenInterceptor())// 对所有请求进行拦截.addPathPatterns("/**")// 排除 login请求.excludePathPatterns("/login");}//解决跨域问题@Beanpublic CorsFilter corsFilter() {UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();source.registerCorsConfiguration("/**", buildConfig());return new CorsFilter(source);}private CorsConfiguration buildConfig() {CorsConfiguration corsConfiguration = new CorsConfiguration();corsConfiguration.addAllowedOrigin("*");corsConfiguration.setAllowCredentials(true);corsConfiguration.addAllowedHeader("*");corsConfiguration.addAllowedMethod("*");return corsConfiguration;}
}

只需要按照上面的代码配置一下就行了,相当与设置允许所有。

除了这种方法,也可以通过Filter来实现。这个也给一下实现吧,和上面的方法任选其一。

java复制代码import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;/*** 自定义拦截器** @author lvhuimin* @version 2019/12/21*/
@Order(1)
@Component
@WebFilter(urlPatterns = "/*", filterName = "cooCorsFilter")
public class CooCorsFilter implements Filter {String ORIGIN = "Origin";@Overridepublic void init(FilterConfig filterConfig) throws ServletException {}@Overridepublic void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain) throws IOException, ServletException {HttpServletRequest httpRequest = (HttpServletRequest) request;HttpServletResponse httpResponse = (HttpServletResponse) response;String origin = httpRequest.getHeader(ORIGIN);httpResponse.setCharacterEncoding("UTF-8");httpResponse.setContentType("application/json; charset=utf-8");httpResponse.setHeader("Access-Control-Allow-Origin", origin);httpResponse.setHeader("Access-Control-Allow-Credentials", "true");httpResponse.setHeader("Access-Control-Allow-Methods", "*");// 如果允许所有header,就用*httpResponse.setHeader("Access-Control-Allow-Headers", "Content-Type,Authorization,token,userId,sysCode,requestSourceType");httpResponse.setHeader("Access-Control-Expose-Headers", "*");filterChain.doFilter(httpRequest, httpResponse);}@Overridepublic void destroy() {}}

这个就是写了一个Filter然后在过滤器中,来加上相应的设置。

好了跨域的问题我们就讲解到这里。但其实还是稍微有点问题,问题就是当我们的SpringBoot项目集成了Swagger的时候,上面的过滤器会和swagger的配置产生冲突,这个等到我们讲到swagger的时候再说。

另: 配套项目代码已托管中gitCode: gitcode.net/lsqingfeng/…

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/410500.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

翻译: Streamlit从入门到精通 高级用法缓存Cache和Session 五

Streamlit从入门到精通 系列: 翻译: Streamlit从入门到精通 基础控件 一翻译: Streamlit从入门到精通 显示图表Graphs 地图Map 主题Themes 二翻译: Streamlit从入门到精通 构建一个机器学习应用程序 三翻译: Streamlit从入门到精通 部署一个机器学习应用程序 四 …

Pytorch基础知识点复习

文章目录 并行计算单卡训练多卡训练单机多卡DP多机多卡DDPDP 与 DDP 的优缺点 PyTorch的主要组成模块Pytorch的主要组成模块包括那些呢?Dataset和DataLoader的作用是什么,我们如何构建自己的Dataset和DataLoader?神经网络的一般构造方法&…

.NET国产化改造探索(三)、银河麒麟安装.NET 8环境

随着时代的发展以及近年来信创工作和…废话就不多说了,这个系列就是为.NET遇到国产化需求的一个闭坑系列。接下来,看操作。 上一篇介绍了如何在银河麒麟操作系统上安装人大金仓数据库,这篇文章详细介绍下在银河麒麟操作系统上安装.NET8环境。…

Ubuntu 22.04 安装prometheus

服务器监控和报警软件有很多,为什么我们会选择Prometheus而不是其他软件呢? 因为它有以下优点: 自带简易web监控页面,用户可以很方便地查看监控数据和使用仪表盘。能实时收集数据并根据自定义警报规则推送告警;具有丰…

AI绘图制作红包封面教程

注意:有不懂的话可加入QQ群聊一起交流:901944946欢迎大家关注微信公众号【程序猿代码之路】,每天都会不定时的发送一些红包封面!! 2024的春节即将到来,而在这春节到来之前,就有一个非常爆火的小…

spring boot学习第八篇:通过spring boot、jedis实现秒单

参考:Redis实现分布式锁的7种方案 - 知乎 1、 准备数据库表,如下SQL表示库存表,有主键ID和库存数量字段 CREATE TABLE t_stock (id bigint(20) NOT NULL AUTO_INCREMENT,quantity bigint(20) NOT NULL,PRIMARY KEY (id) ) ENGINEInnoDB DEF…

0间隔24h采集线报+源码的资源网

一款网站程序零间隔24h采集线报源码的资源网,更新下载类目的采集 及 导入,这款网站程序:jizhiCMS 高仿新版某刀资源网模板进行自动采集。 安装方法: 将根目录文件上传服务器 将根目录文件的sql.sql导入mysql数据库 环境需要支…

【JVM】常用命令

一、前言 Java虚拟机(JVM)是Java程序运行的基础设施,它负责将Java字节码转换为本地机器代码并执行。在开发过程中,我们经常需要使用一些命令来监控和管理JVM的性能和状态。本文将详细介绍6个常用的JVM命令:jps、jstat…

Linux 系统编程:文件系统的底层逻辑 - inode

《Linux 程序设计》的第三章讲文件操作。在提到 目录 时有这么一段文字: 文件,除了本身包含的 内容 以外,它还会有一个 名字 和一些 属性,即“管理信息”,包括文件的创建 / 修改日期和它的访问权限。这些属性被保存在文…

pytorch一致数据增强—独用增强

前作 [1] 介绍了一种用 pytorch 模仿 MONAI 实现多幅图(如:image 与 label)同用 random seed 保证一致变换的写法,核心是 MultiCompose 类和 to_multi 包装函数。不过 [1] 没考虑各图用不同 augmentation 的情况,如&am…

成都谷达冠楠:抖音开网店初期需要注意什么

随着互联网的发展,越来越多的人选择在抖音上开设网店。然而,开店初期需要注意的事项有很多,如果处理不当,可能会影响店铺的正常运营。以下是一些关于抖音开网店初期需要注意的事项。 选择商品非常重要。你需要选择有市场需求的商品…

设计Twitter时间线和搜索功能

设计Twitter时间线和搜索功能 设计 facebook feed 和 设计 facebook search是相同的问题 第一步:定义用例和约束 定义问题的需求和范围,询问问题去声明用例和约束,讨论假设 ps: 没有一个面试官会展示详细的问题,我们需要定义一些用…