javaEE WebServlet、SpringWebMVC、SpringBoot实现跨域访问的4种方式及优先级

news2024/9/24 11:27:12

文章目录

  • 1. 前置知识
  • 2. 原理和解决方案总结
    • 2.1. 跨域不通过原理流程图
    • 2.2. 实现原理:添加以下http响应头
    • 2.3. 四种跨域实现方式及优先级(从高到低)
  • 3. 具体实现代码
    • 3.1. 跨域全局配置方式-Filter(全适用)
    • 3.2. 跨域全局配置方式-SpringMvc
    • 3.3. 跨域单个配置方式-WebServlet
    • 3.4. 跨域单个配置方式-SpringMvc
  • 4.非java实现方式
    • 4.1. nginx代理
  • 9. 参考文章

1. 前置知识

  1. 【尚硅谷】【视频】【B站】禹神:一小时彻底搞懂跨域&解决方案
  2. 【尚硅谷】【笔记】【CSDN】禹神:彻底搞懂前端跨域&解决方案

2. 原理和解决方案总结

2.1. 跨域不通过原理流程图

跨域不通过原理流程图

2.2. 实现原理:添加以下http响应头

序号响应头含义
1Access-Control-Allow-Origin允许的源
2Access-Control-Allow-Methods允许的方法
3Access-Control-Allow-Headers允许的自定义头
4Access-Control-Max-Age预检请求的结果缓存时间(可选)

跨域解决方案原理

2.3. 四种跨域实现方式及优先级(从高到低)

  1. 跨域全局配置方式-Filter(全适用): 重写 Filter.doFilter(),设置 res.setHeader(“Access-Control-Allow-Origin”, “*”) 等响应头参数
  2. 跨域全局配置方式-SpringMvc : 重写 WebMvcConfigurer.addCorsMappings(),设置 registry.addMapping(“/**”).allowedOrigins(“*”)等响应头参数(只对SpringMvc写法生效,对原生Servlet不生效)
  3. 跨域单个配置方式-WebServlet: 设置 res.addHeader(“Access-Control-Allow-Origin”, “*”) 等响应头参数
  4. 跨域单个配置方式-SpringMvc : 添加 @CrossOrigin注解,设置origins等响应头参数(只对SpringMvc写法生效,对原生Servlet不生效)

3. 具体实现代码

  • gitee源码

3.1. 跨域全局配置方式-Filter(全适用)

  • 重写Filter.doFilter(),设置 res.setHeader("Access-Control-Allow-Origin", "*") 等响应头参数
/** 1.跨域全局配置方式-Filter(全适用) */
/** 1.跨域全局配置方式-Filter(全适用) */
@Configuration
public class CorsFilter implements Filter {
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        HttpServletResponse res = (HttpServletResponse) response;
        res.setHeader("Access-Control-Allow-Origin", "*");      //【跨域配置】[必需]               允许请求源  :默认值 无,配置"*"允许所有。
        res.setHeader("Access-Control-Allow-Methods", "*");     //【跨域配置】[有复杂请求方法时必需]  允许请求方法:默认值 无,配置 "*",允许所有
        res.setHeader("Access-Control-Allow-Headers", "*");     //【跨域配置】[有复杂请求头时必需]   允许请求头 : 默认值 无,配置 "*",允许所有
        res.setHeader("Access-Control-Max-Age", "1800");        //【跨域配置】[非必需]             预检缓存时长: 默认值 依赖客户端。EDGE浏览器默认值为3秒。【注意浏览器不要禁用缓存,否则不生效】

        chain.doFilter(request, response);
    }
}

3.2. 跨域全局配置方式-SpringMvc

  • 重写 WebMvcConfigurer.addCorsMappings(),设置 registry.addMapping(“/**”).allowedOrigins(“*”)等响应头参数(只对SpringMvc写法生效,对原生Servlet不生效)
/** 2.跨域全局配置方式-SpringMvc */
@Configuration
public class WebMvcConfig implements WebMvcConfigurer {

    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**")      // 适配@RequestMapping。 (例如:/ajax/** 开头的)
            // 下面几个参数,不配置,会使用默认值。origins 和 originPatterns取并集
            .allowedOrigins("*")                    //【跨域配置】[必需]               允许请求源:默认值为"*",即允许所有。相当于res.setHeader("Access-Control-Allow-Origin", )
            .allowedOriginPatterns("*")             //【跨域配置】[必需]               允许请求源:默认值为"*",即允许所有。相当于res.setHeader("Access-Control-Allow-Origin", )
            .allowedMethods("*")                    //【跨域配置】[有复杂请求方法时必需]  允许请求方法:默认值为GET,POST,HEAD。相当于res.setHeader("Access-Control-Allow-Methods", )
            .allowedHeaders("*")                    //【跨域配置】[有复杂请求头时必需]    允许请求头 :默认值为"*",即允许所有。相当于res.setHeader("Access-Control-Allow-Headers", )
            .maxAge(1800);                          //【跨域配置】[非必需]             预检缓存时长:默认值 1800秒。小于等于0时缓存无效【注意浏览器不要禁用缓存,否则不生效】。相当于res.setHeader("Access-Control-Max-Age", )
    }
}

3.3. 跨域单个配置方式-WebServlet

  • 设置 res.addHeader(“Access-Control-Allow-Origin”, “*”) 等响应头参数

/** 3.跨域单个配置方式-WebServlet */
@Slf4j
@WebServlet(name = "ajax", value = {"/ajax/WebServlet", "/ajax/WebServlet/"})
public class AjaxWebServlet extends HttpServlet {
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse res) throws IOException {
        log.warn("method==【{}】, name==【{}】, header.origin==【{}】, Access-Control-Request-Method==【{}】, Access-Control-Request-Headers==【{}】", req.getMethod(), req.getParameter("name"), req.getHeader("Origin"), req.getHeader("Access-Control-Request-Method"), req.getHeader("Access-Control-Request-Headers"));

        res.setHeader("Access-Control-Allow-Origin", "*");      //【跨域配置】[必需]               允许请求源  :默认值 无,配置"*"允许所有。
        res.setHeader("Access-Control-Allow-Methods", "*");     //【跨域配置】[有复杂请求方法时必需]  允许请求方法:默认值 无,配置 "*",允许所有
        res.setHeader("Access-Control-Allow-Headers", "*");     //【跨域配置】[有复杂请求头时必需]    允许请求头 : 默认值 无,配置 "*",允许所有
        res.setHeader("Access-Control-Max-Age", "1800");        //【跨域配置】[非必需]             预检缓存时长: 默认值 依赖客户端。EDGE浏览器默认值为3秒。【注意浏览器不要禁用缓存,否则不生效】

        res.getWriter().write(DateUtil.now() + "@" + req.getMethod());
    }
}

3.4. 跨域单个配置方式-SpringMvc

  • 添加 @CrossOrigin注解,设置origins等响应头参数(只对SpringMvc写法生效,对原生Servlet不生效)
/* 4.跨域单个配置方式-SpringMvc */
@Slf4j
@RestController
@RequestMapping("/ajax")
public class AjaxController {
    @CrossOrigin(
        // origins 和 originPatterns取并集。【注意】此处配置与下面的res.setHeader()功能相同,优先级较低。二选其一即可
        origins = {"*"},            //【跨域配置】[必需]               允许请求源  :默认值为"*",即允许所有。相当于res.setHeader("Access-Control-Allow-Origin", )
        originPatterns = {"*"},     //【跨域配置】[必需]               允许请求源  :默认值为"*",即允许所有。相当于res.setHeader("Access-Control-Allow-Origin", )
        methods = {},               //【跨域配置】[有复杂请求方法时必需]  允许请求方法:默认值为(优先以@RequestMapping的method属性为准,如果没有指定则默认为"GET,POST,HEAD)。相当于res.setHeader("Access-Control-Allow-Methods", )
        allowedHeaders = {"*"},     //【跨域配置】[有复杂请求头时必需]    允许请求头 :默认值为"*",即允许所有。相当于res.setHeader("Access-Control-Allow-Headers", )
        maxAge = 1800               //【跨域配置】[非必需]             预检缓存时长:默认值 1800秒。小于等于0时缓存无效【注意浏览器不要禁用缓存,否则不生效】 。相当于res.setHeader("Access-Control-Max-Age", )
    )
    @RequestMapping(value = "/CrossOrigin", method = {RequestMethod.GET, RequestMethod.PUT})
    @SneakyThrows
    void ajax(HttpServletRequest req, HttpServletResponse res) {
        log.warn("method==【{}】, name==【{}】, header.origin==【{}】, Access-Control-Request-Method==【{}】, Access-Control-Request-Headers==【{}】", req.getMethod(), req.getParameter("name"), req.getHeader("Origin"), req.getHeader("Access-Control-Request-Method"), req.getHeader("Access-Control-Request-Headers"));

        res.getWriter().write(DateUtil.now() + "@" + req.getMethod());
    }
}

4.非java实现方式

4.1. nginx代理

  • 自己百度,好处是不用侵入java代码

9. 参考文章

  • @CrossOrigin详细参数说明
  • SpringBoot处理跨域请求的四种方法

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

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

相关文章

数字孪生模型制作教程虚拟现实城市模型制作3dmax数字城市glb/gltf

需要做数字孪生可以QQ可以联系这里,谢谢 下面开始教程 1打开3dmax软件,和需要做的建筑图片 2 在3dmax安图片先建一个长方体框架 3先给长方体贴一个墙体贴图 4在ps做贴图 5 做好贴图贴到3dmax中 6 然后ps再做下一张贴图 7 做好贴图贴到3dma…

[Redis] Redisson分布式锁原理及源码分析

目录 基于 Redis 的分布式锁 Redisson实现分布 Redisson分布式锁原理图 RedissonLock实现分布式锁源码分析 RedissonLock构造方法 lock()加锁 获取锁 锁续命逻辑 tryLockInnerAsync加锁lua脚本分析 unlock()解锁 基于 Redis 的分布式锁 实现方式: 使用 Redis 的 SE…

Idea2023.3版本创建spring Initializr没有JDK8

解决方法: https://start.aliyun.com

SOMEIP_ETS_037:echoUINT8RELIABLE_client_closes_TCP_connection_automatically

测试目的: 验证当所有服务停止时,DUT不会关闭TCP连接。 描述 本测试用例旨在检验DUT在停止所有服务时,是否能够保持TCP连接的活跃状态,而不发送FIN,ACK以关闭连接。 测试拓扑: 具体步骤: TESTER&#…

STM32学习笔记3 ---中断,定时器

目录 EXTI外部中断 NVIC嵌套中断向量控制器 EXTI外部中断 AFIO 旋转编码器 定时器TIM TIM定时中断 ​编辑​编辑 ​编辑 TIM输出比较(OC) 引脚重映射 舵机 直流电机 TIM输入捕获(IC) ​编辑 TIM编码器接口 附&#…

漏洞挖掘 | 某系统webpack接口泄露引发的一系列漏洞

信息搜集 这里找到从小穿一条裤子长大的兄弟,要挟他交出来他的统一账号,否则把小时候的照片挂网上,开始某大学的资产搜集,直接hunter搜索此大学域名 看有价值的站点,ok找到下面的站点 未授权敏感信息泄露越权任意用…

力扣高频SQL 50题(基础版)第四十二题之1517.查找拥有有效邮箱的用户

文章目录 力扣高频SQL 50题(基础版)第四十二题1517.查找拥有有效邮箱的用户题目说明实现过程准备数据实现方式结果截图总结 力扣高频SQL 50题(基础版)第四十二题 1517.查找拥有有效邮箱的用户 题目说明 表: Users -----------…

Dify on WeChat

Dify on WeChat 本项目为 chatgpt-on-wechat下游分支 额外对接了LLMOps平台 Dify,支持Dify智能助手模型,调用工具和知识库,支持Dify工作流。 Dify接入微信生态的详细教程请查看文章 手摸手教你把 Dify 接入微信生态 如果我的项目对您有帮助…

gin获得get和post请求参数,获得请求头信息

获得头信息 router.GET("/", func(c *gin.Context) {name : c.Query("id")fmt.Println(name)Token : c.GetHeader("Token")c.JSON(http.StatusOK, Token)})获得get和post信息 package mainimport ("fmt""github.com/SimonWang00…

Leetcode面试经典150题-236.二叉树的最低公共祖先

解法都在代码里,不懂就留言或者私信 /*** Definition for a binary tree node.* public class TreeNode {* int val;* TreeNode left;* TreeNode right;* TreeNode(int x) { val x; }* }*/ class Solution {/**题目分析:本题是经典的二…

仓颉语言运行时轻量化实践

杨勇勇 华为语言虚拟机实验室架构师,目前负责仓颉语言静态后端的开发工作 仓颉语言运行时轻量化实践 仓颉Native后端(CJNative)是仓颉语言的高性能、轻量化实现。这里的“轻量化”意指仓颉程序运行过程中占用系统资源(内存、CPU等…

数据分析:品牌营销如何借势小红书搜索流量

导语 近期,小红书推出《10大搜索趋势洞察》,在找答案这件事上,你永远可以相信小红书。 据悉,70%的小红狐月活用户使用搜索功能,用户平均每天搜索6次,三分之一的用户打开小红书的第一件事就是搜索&#xf…

haproxy知识点整理

haproxy知识点整理 haproxy七层代理负载均衡什么是负载均衡为什么使用负载均衡 负载均衡类型四层负载均衡七层负载均衡四层和七层的区别 环境搭建:客户端(client)haproxy服务器两台服务器hapserver1hapserver2 简单的haproxy负载均衡 haproxy的基本配置信息global配置proxies配…

2024高端网站设计公司推荐TOP3

随着互联网的飞速发展,现在的企业官网已经成为企业不可或缺的一部分,因为企业官网它不仅是企业品牌形象的延伸,也是连接客户、提升市场竞争力的重要工具。 以下简单阐述一下为何现代企业应当投资于高质量网站建设,搭建企业官网有…

html+css 实现图层水波纹效果

html+css 实现图层水波纹效果,废话不多说,直接上代码 <span class="quote-top"><i>水波纹</i><span class="ripple ripple-1"></span><span class="ripple ripple-2"></span><span class="…

打卡第四十一天:买卖股票的最佳时机

一、 买卖股票的最佳时机 题目 文章 视频 确定dp数组&#xff08;dp table&#xff09;以及下标的含义 dp[i][0] 表示第i天持有股票所得最多现金 。其实一开始现金是0&#xff0c;那么加入第i天买入股票现金就是 -prices[i]&#xff0c; 这是一个负数。dp[i][1] 表示第i天…

【MySQL】数据库约束和多表查询

目录 1.前言 2.数据库约束 2.1约束类型 2.2 NULL约束 2.3 NUIQUE&#xff1a;唯一约束 2.4 DEFAULT&#xff1a;默认值约束 2.5 PRIMARY KEY&#xff1a;主键约束 2.6 FOREIGN KEY&#xff1a;外键约束 1.7 CHECK约束 3.表的设计 3.1一对一 3.2一对多 3.3多对多 …

基于火山引擎云搜索服务和豆包模型搭建 RAG 推理任务

大语言模型&#xff08;LLM&#xff0c;Large language model&#xff09;作为新一轮科技产业革命的战略性技术&#xff0c;其核心能力在于深层语境解析与知识融合。在生成式人工智能方向主要用于图像生成&#xff0c;书写文稿&#xff0c;信息搜索等。当下的 LLM 模型是基于大…

【扒网络架构】backbone、ccff

backbone CCFF 还不知道网络连接方式&#xff0c;只是知道了每一层 backbone backbone.backbone.conv1.weight torch.Size([64, 3, 7, 7])backbone.backbone.layer1.0.conv1.weight torch.Size([64, 64, 1, 1])backbone.backbone.layer1.0.conv2.weight torch.Size([64, 64,…

Vue3封装tabs切换组件

效果如下&#xff1a; 代码如下&#xff1a; <template><div class"tabs-container"><div class"tabs-header"><div v-for"tab in tabs" :key"tab.name" class"tab" click"handleTabClick(tab)&…