SpringBoot处理跨域总结

news2024/11/27 9:45:05

解决跨域的五种方法

1、CorsFilter

新建一个类

@Configuration
public class CorsConfig {
    @Bean
    public CorsFilter corsFilter() {
        //1. 添加 CORS配置信息
        CorsConfiguration config = new CorsConfiguration();
        //放行哪些原始域
        //springboot版本为2.4.0以前写法
        config.addAllowedOrigin("*");
        //springboot版本为2.4.0以后写法
        config.setAllowedOriginPatterns(Collections.singletonList("*"));

        //查看项目的springboot版本
        //System.out.println(SpringBootVersion.getVersion());


        //是否发送 Cookie
        config.setAllowCredentials(true);
        //放行哪些请求方式
        config.addAllowedMethod("*");
        //放行哪些原始请求头部信息
        config.addAllowedHeader("*");
        //暴露哪些头部信息
        config.addExposedHeader("*");
        //2. 添加映射路径
        UrlBasedCorsConfigurationSource corsConfigurationSource = new UrlBasedCorsConfigurationSource();
        corsConfigurationSource.registerCorsConfiguration("/**",config);
        //3. 返回新的CorsFilter
        return new CorsFilter(corsConfigurationSource);
    }
}

2、重写 WebMvcConfigurer

@Configuration
public class CorsConfig implements WebMvcConfigurer {
    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**")
                //是否发送Cookie
                .allowCredentials(true)
                //放行哪些原始域
                .allowedOrigins("*")
                .allowedMethods(new String[]{"GET", "POST", "PUT", "DELETE", "OPTIONS", "PATCH"})
                .allowedHeaders("*")
                .exposedHeaders("*");
    }
}

3、使用注解

@RestController
@CrossOrigin(origins = "*")
public class CorsController {
    @RequestMapping("/cors")
    @CrossOrigin(origins = "*")
    public String cors() {
        return "cors";
    }
}

4、手动设置响应头

@RequestMapping("/cors")
public String cors(HttpServletResponse response) {
    response.addHeader("Access-Allow-Control-Origin","*");
    return "cors";
}

5、使用自定义filter

import org.springframework.context.annotation.Configuration;
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@WebFilter(filterName = "CorsFilter ")
@Configuration
public class CorsFilter implements Filter {
    @Override
    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
        HttpServletResponse response = (HttpServletResponse) res;
        response.setHeader("Access-Control-Allow-Origin","*");
        response.setHeader("Access-Control-Allow-Credentials", "true");
        response.setHeader("Access-Control-Allow-Methods", "POST, GET, PATCH, DELETE, PUT, OPTIONS");
        response.setHeader("Access-Control-Max-Age", "3600");
        response.setHeader("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
        chain.doFilter(req, res);
    }
}

模拟跨域

跨域的拦截是浏览器行为,所以后端开发的时候不会遇到这个问题,只有在联调的时候才会发现,这种问题前端、后端都可以解决。前端通过代理请求同一域的一个接口,然后转发到后端。后端则通过在Response Header设置值解决。而后端本地测试跨域配置是否生效时比较麻烦,因为是浏览器问题,发布到测试环境流程长,所以需要本地也能复现跨域问题,其实也比较简单,只不过需要百度一些前端代码[狗头]

首先,先随便找一个网站,然后在Console向本地发送Http请求就能模拟跨域了。

// 普通请求
var xhr = new XMLHttpRequest();
xhr.open('OPTIONS', 'http://127.0.0.1:8080/test1');
xhr.send();
xhr.onload = function(e) {
    var xhr = e.target;
    console.log(xhr.responseText);
}

// GET请求
var xhr = new XMLHttpRequest();
xhr.open('GET', 'http://127.0.0.1:8080/test1?a=1');
xhr.send();
xhr.onload = function(e) {
    var xhr = e.target;
    console.log(xhr.responseText);
}

// 携带header
var xhr = new XMLHttpRequest();
xhr.open('GET', 'http://127.0.0.1:8080/test1?a=1');
xhr.setRequestHeader('content-type', 'application/json');
xhr.setRequestHeader('signature', 'gaejhgkaehguiaehiuavoihvoihviehviehiohao');
xhr.send();
xhr.onload = function(e) {
    var xhr = e.target;
    console.log(xhr.responseText);
}

// POST请求
var xhr = new XMLHttpRequest();
xhr.open('POST', 'http://127.0.0.1:8080/test1?a=1');
xhr.setRequestHeader('content-type', 'application/json');
xhr.setRequestHeader('signature', 'gaejhgkaehguiaehiuavoihvoihviehviehiohao');
xhr.send("{a:1,b:2}");
xhr.onload = function(e) {
    var xhr = e.target;
    console.log(xhr.responseText);
}

跨域问题踩过的坑

这些问题主要是网上代码都是抄来抄去,有一些人抄的时候删了一些或者copy漏了,导致代码不全,然后又因为浏览器的一些机制导致了还是存在跨域问题,坑了后面的人。

踩坑一:没有允许OPTIONS请求跨域

比如用上面的方案二来处理跨域问题

乍一看没有什么问题,只是不支持OPTIONS请求,但是浏览器在处理跨域请求的时候,会先发送一个OPTIONS请求去检测服务是否允许跨域请求,然后再去请求服务要数据之类的。所以这里根本没解决,联调时还是会有跨域问题。

踩坑二:没有允许Credentials

场景:后端不允许前端传递用户凭证,但是前端请求的时候带上了,这时浏览器也会报跨域错误

用户凭证是用户登录之后,服务器下发的一些凭证,如cookie。在跨域请求中,浏览器并不会把cookie携带上,但是可以通过js代码携带上。

使用上面方案一,不允许用户凭证

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

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

相关文章

kaggle竞赛 | Instant Gratification

kaggle比赛链接: https://www.kaggle.com/competitions/instant-gratification/data 目录普通方案优胜方案1. 用方差筛选特征2.QDA二次判别分析3.数据分组(伪标签)4.查看结果赛题总结普通方案 # 数据集路径 INPUT_PATH ../input/import num…

python学习笔记---进程和线程【廖雪峰】

进程和线程 现在,多核CPU已经非常普及了,但是,即使过去的单核CPU,也可以执行多任务。由于CPU执行代码都是顺序执行的,那么,单核CPU是怎么执行多任务的呢? 答案就是操作系统轮流让各个任务交替…

ESP-IDF:企业链表例程,实现初始化,插入,打印等功能。

例程: 简单地写一下企业链表,实现初始化,插入,打印等功能。 /企业链表/ typedef struct LINKNODE09 { // 定义节点 LINKNODE09 *next; } linknode09; // 定义表头 typedef struct LINKLIST09 { // 定义表头 linknode09 head; in…

【胖虎的逆向之路】03——Android一代壳脱壳办法罗列实操

【胖虎的逆向之路】03——Android脱壳办法罗列&脱壳原理详解 【胖虎的逆向之路】01——动态加载和类加载机制详解 【胖虎的逆向之路】02——Android整体加壳原理详解&实现 文章目录【胖虎的逆向之路】03——Android脱壳办法罗列&脱壳原理详解前言一、主流脱壳方法…

uefi和legacy的区别对比

legacy:[ˈleɡəsi],遗产、遗留。 uefi:Unified Extensible Firmware Interface,统一可扩展固件接口。 当我们自己重装或安装操作系统的时候,可能会遇到硬盘的uefi和legacy两种,不过大多数人并不知道uefi和…

低代码开发前景如何?大家都真的看好低代码开发吗?

栖低代码开发前景如何,大家都真的看好低代码开发吗?之前有些过很多关于低代码的内容,这篇就来梳理下国内外低代码开发平台发展现状及前景。 关于低代码解读看这篇>> 什么是低代码(Low-Code)? 关于低…

SpreadJS.Release.16.0.2 Crack by Xacker

SpreadJS拥有 500 多个 Excel 函数的世界销量第一的 JavaScript 电子表格 快速提供真正类似 Excel 的电子表格体验 - 对 Excel 零依赖。创建财务应用程序,仪表板,图表,数据透视表,性能基准,科学实验室笔记本,以及其他类似的 JavaScript 电子表格应用程序…

77. 语言模型以及代码实现

1. 语言模型 给定文本序列 x1,…,xT,语言模型的目标是估计联合概率p(x1,…,xT)它的应用包括 做预训练模型(eg BERT,GPT-3)生成文本,给定前面几个词,不断使用xt~p(x1,…,xt-1) 来生成后续文本判…

CSS选择器整理学习(上)

在前端项目开发中,有时候需要对特殊的元素进行特殊的处理,但有时候元素的位置不确定、层级不确定、数量不确定等问题,导致我们没办法进行元素的选择,这个时候我们就需要用到元素选择器了。 一、CSS选择器 1、.class 选择器例子…

图像处理解决流程--外观检测

一、图像外观检测和面积计算 1、获取标准图像,提取要测定的区域(截取成多个ROI) 2、将目标图像的位置进行平移和旋转(将目标图像和标准图像进行重叠) 3、根据标准图像的区域进行以此计算目标图像的信息 4、判断统计 二…

Ajax基础

Ajax 是 Asynchronous JavaScript and XML(异步 JavaScript 和 XML)的简写 Ajax 中的异步:可以异步地向服务器发送请求,在等待响应的过程中,不会阻塞当前页面,浏览器可以做自己的事情。直到成功获取响应后…

Maven高级进阶

文章目录1,分模块开发1.1 分模块开发设计1.2 分模块开发实现1.2.1 环境准备1.2.2 抽取domain层步骤1:创建新模块步骤2:项目中创建domain包步骤3:删除原项目中的domain包步骤4:建立依赖关系步骤5:编译maven_02_ssm项目步骤6:将项目安装本地仓库1.2.3 抽取Dao层步骤1:…

iOS vue devtools工具的手把手安装,及Vue.js not detected的解决

使用vue插件Vue.js devtools 一.通过谷歌商店直接下载(要翻墙) 二.不翻墙的方法: 1.官网下载 git地址:https://github.com/vuejs/devtools git clone https://github.com/vuejs/devtools2.完成后命令行里切到该目录下&#x…

AppScan绕过登录验证码深入扫描

系列文章 AppScan介绍和安装 AppScan 扫描web应用程序 AppScan被动手动探索扫描 第四节-绕过登录验证码深入扫描 我们工作中最长碰到的工作场景是网站采用https协议,这时我们要用appScan进行扫描时,就需要先安装证书 1.证书安装 1.新建一个文件&…

渗透测试— —扫描与爆破账号

渗透测试— —扫描与爆破靶机账号 1 扫描与爆破账号流程 注意:仅用于教学与实验,不能用于攻击,否则后果自负 扫描:主机探测与端口扫描。(主机探测:目标主机是存活,端口扫描:在线主…

总结 62 种在深度学习中的数据增强方式

数据增强 数据增强通常是依赖从现有数据生成新的数据样本来人为地增加数据量的过程 这包括对数据进行不同方向的扰动处理 或使用深度学习模型在原始数据的潜在空间(latent space)中生成新数据点从而人为的扩充新的数据集 这里我们需要区分两个概念,即增强数据和…

SpringBoot的filter过滤器

SpringBoot的filter过滤器 目录SpringBoot的filter过滤器一、过滤器的作用和概述1.1 简述1.2 使用场景二、自定义过滤的两种方式2.1 第一种方式2.1.1 启动类增加注解ServletComponentScan2.1.2 定义一个filter类2.1.3. 测试2.2 第二种方式2.2.1 自定义fitler类2.2.4 在启动类中…

《Linux Shell脚本攻略》学习笔记-第五章

5.1 简介 借助HTTP协议所提供的功能以及命令行实用工具,我们可以用脚本满足大量的web自动化需求。 5.2 web页面下载 wget是一个用于文件下载的命令行工具,选项繁多且用法灵活。 下载单个文件或web页面 指定从多个URL处进行下载 我们可以通过选项-O指定输…

centos上用nginx搭建简单的点播服务器

查看centos系统信息:cat /etc/centos-release配置服务器DNSecho "nameserver 114.114.114.114" >> /etc/resolv.conf 安装网络工具yum install ntpdate wget net-tools -y同步服务器时间ntpdate ntp.aliyun.com安装编译工具及依赖库yum install -y …

【原生Button和antd的Button】

1. 原生Button 1. form 与按钮所关联的form元素。此属性的值必须是同一文档中form的id。如果未设置此属性&#xff0c;则 < Button>与其祖先< form>元素相关联 此属性允许将< Button>元素关联到文档中的任意位置< form>&#xff0c;而不仅仅是< …