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 {

    // 昨天的拦截器注册
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        //拦截
        registry.addInterceptor(new TokenInterceptor())
                // 对所有请求进行拦截
                .addPathPatterns("/**")
                // 排除 login请求
                .excludePathPatterns("/login");
    }

    //解决跨域问题
    @Bean
    public 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";
 
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
 
    }
 
    @Override
    public 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);
    }
 
    @Override
    public void destroy() {
 
    }
 
}

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

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

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

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

PRU pruss, rproc_pru和prueth uboot源码分析

概述 首先看一下PRU_ICSSG的功能框图,对于AM64来说,包含两个PRU_ICSSG模块。每个PRU_ICSSG共包含两个slice。 每个PRU core自己Local Instruction RAM, 容量不同。 PRU 内核执行任何指令之前,…

NXP-RT1176开发(一)——环境搭建(MCUXpressoIDE/VSCode)

目录 1. 安装IDE 1.1 官方开发的IDE软件 1.2 Config工具下载 1.3 说明(需先有SDK) 2. 下载SDK 3. VScode环境下编译 3.1 安装插件 3.2 确保本地有交叉编译工具链和CMAKE 3.3 加载本地SDK 3.4 导入例程编译 1. 安装IDE 该处理器编译规则可以MDK…

科普丨数据泄露防护DLP是什么(DLP数据泄露防护系统推荐)

在数字化时代,数据泄露的风险日益严峻,给企业和组织带来了巨大的威胁。为了应对这一挑战,数据泄露防护DLP(Data Loss Prevention)应运而生,成为保护数据安全的重要手段之一。 一、DLP数据泄露防护系统是什么…

高级RAG技术、以及算法实现

知识库地址:Advanced RAG techniques 检索增强生成(Retrieval Augmented Generation, RAG)为大语言模型(Large Language Model, LLM)提供了一种机制,通过从数据源检索到的信息为其生成的答案提供依据。简而…

C语言--质数算法和最大公约数算法

文章目录 1.在C语言中,判断质数的常见算法有以下几种:1.1.试除法(暴力算法):1.2.优化试除法:1.3.埃拉托色尼筛法:1.4.米勒-拉宾素性检验:1.5.线性筛法:1.6.费马小定理&am…

【前端发版】vue前端发版 步骤

1、 提交代码 代码合并通过之后到deb分支 2、git checkout 切换到dev分支上 运行起来看看自己刚刚提交的代码有没有错误 3、拉取最新代码 git pull 3、yarn run build 4、打包好的文件叫dist 重新命名为服务器里替换包名 5、登录文件传输 开始替换 替换的过程中 首先删除备…

如何一台电脑操作两个adb 设备

1.首先使用 adb devies 命令 2.然后使用 adb -s 上面的返回的id号 shell 进入对应的开发板

优化您的服务请求,增强用户体验和服务交付

您的服务请求模板是否像一个复杂的迷宫,给您的团队带来延误和困惑?您的技术人员是否厌倦了为了解最终用户的需求而与他们来回奔波?强大且可定制的请求模板可能正是您所需要的! 服务交付团队(尤其是 IT)的…

ubuntu服务器安装Slurm

相关内容,网上不少,这里记录一下自己出现的问题和解决方法,采用的是Ubuntu22.04,方法可以参考知乎上面这篇文章Ubuntu服务器安装配置slurm,整个安装过程没有什么问题,主要步骤贴在这里但在使用过程中&#…

Vue3响应式系统(一)

一、副作用函数。 副作用函数指的是会产生副作用的函数。例如:effect函数会直接或间接影响其他函数的执行,这时我们便说effect函数产生了副作用。 function effect(){document.body.innerText hello vue3 } 再例如: //全局变量let val 2f…

【MATLAB】Linux版本 高分辨率屏 调整显示缩放

0 引言 安装了linux版本的MATLAB R2023b之后,发现工具栏字体很小不方便使用,所以上网找到了MATLAB论坛上某位大佬的教程:参考链接,放在这里供各位参考 。 1 环境 这里注明我的matlab安装环境仅供参考,未在其他环境下…

Java基础 - 黑马

我是南城余!阿里云开发者平台专家博士证书获得者! 欢迎关注我的博客!一同成长! 一名从事运维开发的worker,记录分享学习。 专注于AI,运维开发,windows Linux 系统领域的分享! 知…

msvcp140.dll丢失都有什么办法可以解决呢?分享几种解决办法

msvcp140.dll是Windows操作系统中的一个重要动态链接库文件,它与许多软件的正常运行密切相关。当系统或软件无法找到或访问到该dll文件时,就会出现msvcp140.dll丢失的问题。这可能导致某些软件无法启动或崩溃,给用户带来不便。为了解决这个问…

Proxy的使用方法和13种拦截操作

前言 proxy是ES6新推出的方法,功能很强大。属于元编程,也就是修改js本身的一些东西。可以对数组,对象,函数等引用类型的对象进行一些复杂的操作。 其中,大部分人应该最熟悉的莫过于vue3中使用proxy替换了defineProperty,而且还实现了本身defineProperty不能实现的一些东西。 …

GO——gin中间件和路由

中间件 参考:https://learnku.com/articles/66234 结构 中间件是函数中间件函数被放在调用链上调用链的末尾是路由path对应的函数 执行过程 net/http包调用到gin的serverHTTP 参考:go/pkg/mod/github.com/gin-gonic/ginv1.7.7/gin.go:506 通过path找到…

FlinkSQL【分组聚合-多维分析-性能调优】应用实例分析

FlinkSQL处理如下实时数据需求: 实时聚合不同 类型/账号/发布时间 的各个指标数据,比如:初始化/初始化后删除/初始化后取消/推送/成功/失败 的指标数据。要求实时产出指标数据,数据源是mysql cdc binlog数据。 代码实例 --SET t…

【.net core】yisha框架,bootstrap-table组件增加固定列功能

需要引入 bootstrap-table-fixed-columns.css和bootstrap-table-fixed-columns.js文件 文件代码: bootstrap-table-fixed-columns.css样式文件代码 .fixed-table-header-columns, .fixed-table-body-columns {position: absolute;background-color: #fff;displa…

【Vue3】3-2 : 组件的概念及组件的基本使用方式

本书目录:点击进入 一、组件的概念 1.1、【案例】评分组件与按钮组件的抽离过程 二、组件的使用 - 抽离结构 2.1、【案例】简易首页 > 效果 > 代码 - 原始 > ​​​​​​​代码 - 组件抽离结构 > ​​​​…

【汇编】实验11 编写子程序

综合一下学过的指令就行了,比较简单。 assume cs:code data segmentdb "Beginners All-purpose Symbolic Instruction Code.",0 data ends code segment begin:mov ax,datamov ds,axmov si,0call lettercmov ax,4c00hint 21h letterc:mov cl,[si]mov ch,…