Spring Boot项目中解决跨域问题(四种方式)

news2024/11/14 18:38:57

目录

  • 一,跨域产生的原因
  • 二,什么情况下算跨域
  • 三,实际演示
  • 四,解决跨域的方法
    • 1,@CrossOrigin注解
    • 2,添加全局过滤器
    • 3,实现WebMvcConfigurer
    • 4,Nginx解决跨域
    • 5,注意

开发项目的时候因为浏览器同源策略的限制,经常会遇到跨域问题,本篇文章对常见的跨域解决方案做一个记录。

一,跨域产生的原因

之所以产生跨域主要是因为浏览器同源策略的限制。
同源策略,它是由NetSpace提出的一个著名的安全策略。
当一个浏览器的两个tab页中分别打开来自百度和谷歌的页面,当浏览器的百度tab页执行一个脚本的时候会检查这个脚本是属于哪个页面的,即检查是否同源,只有和百度同源的脚本才会被执行。如果非同源,那么在请求数据时,浏览器会在控制台中报一个异常,提示拒绝访问。

二,什么情况下算跨域

一个域名地址由以下几个部分组成:
http://www.aaa.com:8080/s?ie=UTF-8&wd=SpringBoot

  • 协议:http
  • 域名:子域名www,主域名aaa.com
  • 端口:8080

从一个域名的网页去请求另一个域名的资源时,协议,域名,端口任意不同,都会出现跨域问题。
http://www.aaa.com:8080——>http://www.aaa.com:8080:同域访问
http://www.aaa.com:8080——>http://www.bbb.com:8080:跨域访问

尤其是在前后端分离的开发模式下,跨域请求是避免不了的。

三,实际演示

下面我们以一个实际功能为例:用户输入用户名密码,发往服务端验证。
在这里插入图片描述
因为浏览器同源策略的限制,在浏览器控制台提示我们:
Access to XMLHttpRequest at ‘http://192.168.1.10:7080/tick-tack/login’ from origin ‘http://192.168.1.10:7060’ has been blocked by CORS policy: Response to preflight request doesn’t pass access control check: No ‘Access-Control-Allow-Origin’ header is present on the requested resource.
我们还可以在Network里看到,浏览器在发送我们输入的用户名,密码等数据之前,还发送了一次OPTIONS的请求,这是浏览器自动发送的,为了验证是否允许跨域访问。
在这里插入图片描述

四,解决跨域的方法

我们已经知道,浏览器在发送请求之前会先发送一个OPTIONS请求,来校验是否允许跨域访问,校验的结果存放在头信息的Access-Control-Allow-Origin,因此解决跨域也就是设置头部信息。有四种方法解决跨域。

1,@CrossOrigin注解

我们可以在特定的某些接口加上@CrossOrigin注解,表示该接口允许跨域访问。注:未加该注解的接口仍不允许跨域访问

@PostMapping("/login")
@CrossOrigin
public Result loginSystem(@RequestBody LoginUser user) {
    if (StringUtils.isBlank(user.getUserAccount()) || StringUtils.isBlank(user.getPassword())) {
        return Result.error(Constants.CODE_400, "参数错误");
    }

    TickToken tickToken = ILoginService.loginSystem(user);

    return Result.success(tickToken);
}

@CrossOrigin注解中的origins还可设置域名,表示只有该域名访问时允许跨域,如:@CrossOrigin(origins =“http://localhost:7060”);
若origins未设置值,表示所有域名都可以跨域访问该接口
在这里插入图片描述

2,添加全局过滤器

若项目中所有接口都允许跨域访问,可增加全局过滤器允许跨域访问。

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;

@Configuration
public class CorsConfig {
    // 当前跨域请求最大有效时长。这里默认1天
    private static final long MAX_AGE = 24 * 60 * 60;

    @Bean
    public CorsFilter corsFilter() {
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        CorsConfiguration corsConfiguration = new CorsConfiguration();
        corsConfiguration.addAllowedOrigin("*"); // 1 设置访问源地址,或者http://localhost:7060
        corsConfiguration.addAllowedHeader("*"); // 2 设置访问源请求头
        corsConfiguration.addAllowedMethod("*"); // 3 设置访问源请求方法,或设置为"GET", "POST", "DELETE", "PUT"
        corsConfiguration.setMaxAge(MAX_AGE);
        source.registerCorsConfiguration("/**", corsConfiguration); // 4 对接口配置跨域设置
        return new CorsFilter(source);
    }
}

3,实现WebMvcConfigurer

import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
public class WebConfig implements WebMvcConfigurer {
    // 当前跨域请求最大有效时长。这里默认1天
    private static final long MAX_AGE = 24 * 60 * 60;

    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**")
                .allowedOrigins("*")
                .allowedMethods("*")
                .allowedHeaders("*")
                .maxAge(MAX_AGE);
    }
}

4,Nginx解决跨域

如果项目中有使用Nginx来转发请求,那也可以交由Nginx来解决跨域,但是有一点需要注意:Nginx解决跨域和后端解决跨域最好只保留一个,两种混用会出现很多奇怪的问题。
下面是nginx.conf文件解决跨域的相关配置:

server {
        listen       80;
        server_name  localhost;
        location  / {
            if ($request_method = 'OPTIONS') {
                add_header Access-Control-Allow-Origin 'http://localhost:7060';
                add_header Access-Control-Allow-Headers '*';
                add_header Access-Control-Allow-Methods '*';
                add_header Access-Control-Allow-Credentials 'true';
                return 204;
            }
            if ($request_method != 'OPTIONS') {
                add_header Access-Control-Allow-Origin 'http://localhost:7060' always;
                add_header Access-Control-Allow-Credentials 'true';
            }
            proxy_pass  http://localhost:59200; 
        }
    }

5,注意

说明: 文章中很多地方为了方便,Access-Control-Allow-Origin设置成了*,这个在开发测试的时候可以这么设置,但如果是生产环境,建议不要设置成*,最好是允许哪些域名访问就设置哪些,毕竟限制域名还是很有必要的。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

黑马Java——集合进阶(List、Set、泛型、树)

一、集合的体系结构 1、单列集合(Collection) 二、Collection集合 1、Collection常见方法 1.1代码实现: import java.util.ArrayList; import java.util.Collection;public class A01_CollectionDemo1 {public static void main(String[] a…

Android实现底部导航栏方法(Navigation篇)

Navigation实现底部导航栏 前言导入和基本使用导入基础使用创建nav文件编辑Nav文件添加页面(代码版)添加页面(图解版) 创建导航动作 action创建action(代码版)创建action(图解版) 编…

Linux的进程信号

注意:首先需要提醒一个事情,本节提及的进程信号和下节的信号量没有任何关系,请您区分对待。 1.信号概念 1.1.生活中的信号 我们在生活中通过体验现实,记忆了一些信号和对应的处理动作,这意味着信号有以下相关的特点&…

上位机图像处理和嵌入式模块部署(统计函数执行时间)

【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing 163.com】 和pc上位机相比较,嵌入式设备的计算资源很多时候都是不足的。但是,嵌入式设备胜在稳定性和成本上面,这方面又是…

【XR806开发板试用】xr806使用tcp socket与手机通信

本文为极术社区XR806开发板活动试用文章。 参考:基于星辰处理器的全志XR806开源鸿蒙开发板上手体验 搭建环境。并成功编译。 项目源码 : https://gitee.com/kingwho/smart-home 在同一个局域网中,手机与xr806连接后,手机 APP 每隔…

lnmp一键安装包+wordpress

理论知识 1. LNMP组成介绍​ LNMP代表的是Linux系统下NginxMySQLPHP组成的动态网站系统解决方案。如图所示,Linux是目前最流行的免费操作系统;Nginx性能稳定、功能丰富、处理静态文件速度快且消耗系统的资源极少;MySQL是一个性能卓越、服务稳…

手拉手Vue3+vite引入echarts

技术栈springboot3hutool-alloshi-coreVue3viteechartsTailwindCSS软件版本IDEAIntelliJ IDEA 2022.2.1JDK17Spring Boot3.1hutool-all5.8.18oshi-core6.4.1Vue35.0.10vite5.0.10axios1.6.7echarts5.4.3 ECharts是一个使用 JavaScript 实现的开源可视化库,可以流畅…

awd总结

总结: 由于是第一次参加AWD比赛,各方面经验都不足,在参赛的前几天也是疯狂搜集各种脚本、框架、工具等,同时也参考b站的视频进行学习,我发现就是还是实操才能更快的学习 我觉得就是我前期的准备工作不足,…

stm32软件安装以及创建工程

文章目录 前言一、软件安装软件破解 二、创建工程三、创建项目创建组配置启动文件添加到组 为项目添加头文件路径创建源文件(main函数文件)使用寄存器配置引脚拼接好STLINK与stm32最小电路板的接线编写程序配置STLink下载程序配置寄存器配置13号端口&…

智能化运维发展现状?智能化运维方向有哪些?

智能运维方向主要包括人工运维、自动运维和智能运维三个阶段。从以下几个方面可以简要介绍智能运维的发展情况:  市场参与者众多:我国智能运维领域参与者众多,市场份额相对较低。华为、浪潮云、联想等硬件制造商在市场上占有很大份额。  …

c语言游戏实战(3):三子棋

前言: 三子棋是一种民间传统游戏,又叫九宫棋、圈圈叉叉棋、一条龙、井字棋等。游戏规则是双方对战,双方依次在9宫格棋盘上摆放棋子,率先将自己的三个棋子走成一条线就视为胜利。但因棋盘太小,三子棋在很多时候会出现和…

vulnhub中Beelzebub靶机

渗透思路 一.信息收集1.网段探测2.端口探测3.常见漏洞扫描4.目录扫描5.web页面分析 二.渗透继续目录扫描ssh连接提权提权,flag 一.信息收集 1.网段探测 ┌──(root㉿kali)-[~] └─# nmap -Pn 192.168.0.0/24 --min-rate 10000 Starting …

day28打卡

day28打卡 93. 复原 IP 地址 见注释 class Solution { public:vector<string> ret;vector<string> restoreIpAddresses(string s) {string ip;dfs(s, 0, ip);return ret;}//n记录小数点个数void dfs(string s, int n, string ip){//n为4if(n 4){//如果字符s没有…

2024Node.js零基础教程(小白友好型),nodejs新手到高手,(四)NodeJS入门——网络基础概念

041_网络基础概念_IP的介绍 hello&#xff0c;大家好&#xff0c;我们来一起认识一下IP。 在开始介绍 IP 之前&#xff0c;我们首先来介绍一个场景&#xff0c;方便大家去理解 IP 这个概念。比如这会儿强哥正在成都&#xff0c;然后还有另外一个小伙伴&#xff0c;谁呢&#x…

数据库分库分表:提升系统性能的必由之路

欢迎来到我的博客&#xff0c;代码的世界里&#xff0c;每一行都是一个故事 数据库分库分表&#xff1a;提升系统性能的必由之路 前言为什么分库分表是必要的分库分表的基本概念和原理性能提升和负载均衡 前言 在数字化时代&#xff0c;数据被认为是企业最宝贵的资产之一。然而…

STA双WiFi连接

STA双WiFi连接 1、STA/STA双WiFi开关1.1 相关属性1.2 STA/STA支持判断 2、STA双WiFi命令测试2.1 adb shell cmd wifi add-suggestion guest_5G wpa3 12345678 -p2.2 adb shell cmd wifi remove-suggestion guest_5G2.3 查看dumpsys wifi信息WifiConfigStore 3、STA双WiFi连接流…

Graal编译器和GraalVM虚拟机

文章目录 说明Java程序执行流程JVM的语言无关性JVM的执行流程执行引擎的两种行为&#xff1a;解释执行和编译热点代码和热点代码探测方式热点代码热点代码探测方式热点代码探测方式流程 HotSpotVM内嵌两个JIT编译器Graal编译器GraalVMGraalVM虚拟机安装和体验GraalVM的下载和安…

【JavaEE】_传输层协议UDP与TCP

目录 1. 开发中常见的数据组织格式 1.1 XML 1.2 JSON 1.3 Protobuf 2. 端口号 3. UDP协议 4. TCP协议 4.1 特点 4.2 TCP报文格式 4.3 TCP可靠性机制 4.3.1 确认应答机制 4.3.2 超时重传机制 4.3.2.1 丢包的两种情况 4.3.2.2 重传时间 4.3.3 连接管理机制 4.3.3…

【Flink入门修炼】1-2 Mac 搭建 Flink 源码阅读环境

在后面学习 Flink 相关知识时&#xff0c;会深入源码探究其实现机制。因此&#xff0c;需要现在本地配置好源码阅读环境。 本文搭建环境&#xff1a; Mac M1&#xff08;Apple Silicon&#xff09;Java 8IDEAFlink 官方源码 一、 下载 Flink 源码 github 地址&#xff1a;h…

【Vue3+Vite】Vue生命周期与组件 快速学习 第三期

文章目录 一、Vue生命周期1.1 生命周期简介1.2 生命周期案例 二、Vue组件2.1 组件基础2.2 组件化入门案例2.3 组件之间传递数据2.3.1父传子2.3.2 子传父2.3.3 兄弟传参 总结 一、Vue生命周期 1.1 生命周期简介 每个 Vue 组件实例在创建时都需要经历一系列的初始化步骤&#xf…