CORS解决浏览器跨域请求(同源策略)限制原理、后端springboot CROS跨域解决方案

news2024/9/24 6:36:55

文章目录

  • 1 浏览器的同源策略
    • 1.1 什么是源(origin)?
    • 1.2 跨域请求?
    • 1.3 同源策略(跨域限制)是什么?
      • 1.3.1 同源策略的具体限制?
      • 1.3.2 浏览器CORS校验
  • 2 CORS解决Ajax跨域问题
    • 2.1 CORS概述
    • 2.2 CORS解决简单请求跨域
      • 2.2.1 简单请求
      • 2.2.2 简单请求CORS解决方案
    • 2.3 CORS解决复杂请求跨域
      • 2.3.1 复杂请求
      • 2.3.2 预检请求
      • 2.3.3 复杂请求CORS解决方案
  • 3 Springboot CROS跨域解决方案
    • 3.1 配置全局跨域访问
      • 3.1.1 继承WebConfigConfigurer
      • 3.1.2 配置cors过滤器,新建自己的bean覆盖原来的
    • 3.2 配置局部跨域访问
      • 3.2.1 @CrossOrigin注解(和controller配合使用)
      • 3.2.2 HttpServletResponse中设置header

1 浏览器的同源策略

1.1 什么是源(origin)?

源=协议+域名+端口号

注意点 :

  • 不看后面跟着的路径,如http://localhost:8080/usr/home 的源是http://localhost:8080
  • httphttps是两种连接协议

1.2 跨域请求?

首先了解两个概念:

  • 所处源:浏览器页面显示的源
  • 目标源:请求的服务器源

所处源和目标源不一致就是非同源,就是跨域,因此若前后端跨域,那么前端发送的就是跨域请求。

1.3 同源策略(跨域限制)是什么?

同源策略是浏览器为了确保资源安全而遵循的一种策略,他会对访问的资源进行限制。也就是说,这一策略是浏览器执行的。
需要注意的是:

  • 跨域限制仅仅存在浏览器端,服务端不存在跨域限制(两个源不同的服务器之间理论上可以互相请求并接收数据)
  • 浏览器对标签跨域没有限制,比如<src>、<script>、<img>里面有一些跨域请求是可以正常响应的

1.3.1 同源策略的具体限制?

  • Dom限制:源A的脚本无法读取源B的Dom(内嵌iframe可以显示,但是无法通过js代码获取Dom元素)
  • Cookie限制:源A无法访问源B的cookie(用户信息安全)
  • Ajax响应数据限制:源A可以给源B发送请求,源B也可以正常响应并返回数据,但是响应结果会被浏览器拦截(实际开发最常碰见的问题)

那么,浏览器是如何进行拦截的呢?

1.3.2 浏览器CORS校验

下图是前后端响应时序图,js代码运行在浏览器上,通过浏览器向后端服务器发送ajax请求,服务器正常响应并返回数据,但此时浏览器会做一次校验,校验通过才能正常显示数据,否则会对数据进行拦截并抛出异常。
这个校验的过程就是同源策略执行的时间点,浏览器会根据CORS(Cross-Origin Resource Sharing)规范进行校验,若浏览器和服务器处于同一源则检验通过,否则不通过。
在这里插入图片描述

2 CORS解决Ajax跨域问题

2.1 CORS概述

CORS(Cross-Origin Resource Sharing,跨域资源共享)是用于控制浏览器校验跨域请求的一套规范,若要解决跨域限制,服务器需要依照CORS规范,添加特定响应头来控制浏览器校验,大致规则如下:

  • 服务器明确表示拒绝跨域请求或没有表示的,则校验不通过
  • 服务器表示允许跨域请求,则浏览器校验通过

由于要求服务器在响应体添加相关字段来通过校验,所以服务器必须是自己人,比如无法向百度的接口发送跨域请求,因为人家不认识你,就无法在响应体头里配置源。

2.2 CORS解决简单请求跨域

2.2.1 简单请求

简单请求,需要同时满足以下三个条件:

  1. 请求方法为GET、HEAD、POST
  2. 请求头字段符合《CORS安全规范》(只要不修改请求头,如添加字段,基本都符合)
  3. 请求头的content-type必须是‘text/plain’‘multipart/form-data’‘application/x-www-form-urlencoded’

2.2.2 简单请求CORS解决方案

浏览器在发送请求的时候,请求头里会携带‘origin’字段标明请求的源,所以服务器若允许跨域请求,只要在响应头(Header)的‘Access-Control-Allow-Origin’字段添加可以跨域访问的源即可。
如:

//request header:
`……
Origin:http://127.0.0.1:1234
……`
//Response header:
`……
Access-Control-Allow-Origin:http://127.0.0.1:1234
……`

注意:

  • 响应体里的访问允许源要完全和请求源一致,不能在末尾多一个斜杠
  • localhost和127.0.0.1要区分开,origin和acao保持一致

2.3 CORS解决复杂请求跨域

2.3.1 复杂请求

只要不满足简单请求的任一条件,就是复杂请求。

2.3.2 预检请求

进行复杂请求前会先发送一个预检请求(浏览器自动发起),用来向服务器确认是否允许接下来的【一系列】跨域请求。预检请求是一个options请求,只有通过了预检请求才会继续发起实际的跨域请求。
预检请求头一般包括:

字段解释
Origin请求源
Access-Control-Request-Method实际请求(复杂请求本身,非预检请求)的HTTP方法
Access-Control-Request-Headers实际请求中使用的自定义头(自定义的头字段)

2.3.3 复杂请求CORS解决方案

Step 1: 服务器首先需要通过浏览器的预检请求,那么需要在响应头里返回如下字段:

字段解释
Access-Control-Allow-Origin允许的源
Access-Control-Allow-Methods允许的方法
Access-Control-Allow-Headers允许的自定义头
Access-Control-Max-Age预检请求的结果缓存时间(可选,设定该字段后,在设定时间内满足访问条件的复杂请求将不再重复发送预检请求,而是直接进行复杂请求)

Step 2: 处理实际跨域请求,这一步同简单请求,在响应头‘Access-Control-Allow-Origin’字段添加源

3 Springboot CROS跨域解决方案

介绍了允许跨域请求的原理后,就可以根据相关字段在后端进行配置,以通过同源策略。

3.1 配置全局跨域访问

3.1.1 继承WebConfigConfigurer

新建跨域config类,继承WebConfigConfigurer,重写addCorsMappings方法:

@Configuration
public class WebMvcConfig  implements WebMvcConfigurer {
    @Override
public void addCorsMappings(CorsRegistry registry) {      
//添加映射路径,哪些请求的url路径可以进行处理,一般会将url和controller进行绑定,"/**"则表示所有路径都进行处理
        registry.addMapping("/**")                 
//表示允许所有的域都可以请求
                .allowedOrigins("*")
                //表示在3600秒内不需要再发送预校验请求
                .maxAge(3600)
                //是否发送Cookie信息
                .allowCredentials(true)
                //表示允许跨域请求的方法
                .allowedMethods("GET","POST", "PUT", "DELETE")
                //表示允许跨域请求包含content-type
                .allowedHeaders("*")
                //暴露哪些头部信息(因为跨域访问默认不能获取全部头部信息,如果需要获取则在exposedHeaders里定义好需要暴露的字段)
                .exposedHeaders("Header1", "Header2");
    }
}

3.1.2 配置cors过滤器,新建自己的bean覆盖原来的

@Configuration
public class CorsFilterConfig {
    @Bean
    public CorsFilter corsFilter() {
        CorsConfiguration config = new CorsConfiguration();
          config.addAllowedOrigin("*");
          config.setAllowCredentials(true);
          config.addAllowedMethod("*");
          config.addAllowedHeader("*");
          config.addExposedHeader("*");
 
UrlBasedCorsConfigurationSource configSource = new UrlBasedCorsConfigurationSource();
        configSource.registerCorsConfiguration("/**", config);
        return new CorsFilter(configSource);
    }
}

3.2 配置局部跨域访问

3.2.1 @CrossOrigin注解(和controller配合使用)

注解常用属性(若不加属性则表示没有限制):

字段解释
origins指定允许访问的源
allowedHeaders指定允许的请求头
allowedMethods指定允许的HTTP方法
exposedHeaders指定允许暴露的响应头
allowCredentials指定是否允许发送身份验证信息(如cookie)
maxAge指定预检请求(OPTIONS)的缓存时间,单位为秒

用在类上
则该类所有方法都可以被允许的域访问:

@Controller
@CrossOrigin("http://localhost:1234")
public class EmpController {
    @RequestMapping("/test")
    public String getTestInfo() {
        return “testinfo”;
}
@RequestMapping("/test2")
    public String getTestInfo2() {
        return “testinfo2”;
    }
}

用在方法上
没有配置@CrossOrigin的方法无法进行跨域访问:

@Controller
public class EmpController {
//可以跨域访问
@CrossOrigin("http://localhost:1234")
@RequestMapping("/test")
    public String getTestInfo() {
        return “testinfo”;
}
//不可以跨域访问
@RequestMapping("/test2")
    public String getTestInfo2() {
        return “testinfo2”;
    }
}

3.2.2 HttpServletResponse中设置header

每个都要设置,太麻烦。

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

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

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

相关文章

周家庄智慧旅游小程序

项目概述 周家庄智慧旅游小程序将通过数字化手段提升游客的旅游体验&#xff0c;依托周家庄的自然与文化资源&#xff0c;打造智慧旅游新模式。该小程序将结合虚拟现实&#xff08;VR&#xff09;、增强现实&#xff08;AR&#xff09;和人工智能等技术&#xff0c;提供丰富的…

Java 中的垃圾回收综合讲解

Java 垃圾收集综合指南 Java 中的垃圾收集 (GC) 是 Java 虚拟机 (JVM) 通过删除应用程序中不再可访问的对象来自动回收内存的过程。这有助于防止内存泄漏并优化活动对象的可用内存&#xff0c;从而保持 Java 应用程序的性能和效率。 在 Java 中配置垃圾收集器 要在 Java 中…

Java语言程序设计基础篇_编程练习题***18.33 (游戏:骑士旅途的动画)

目录 ***18.33 (游戏:骑士旅途的动画) 习题思路 代码示例 动画演示 ***18.33 (游戏:骑士旅途的动画) 为骑士旅途的问题编写一个程序&#xff0c;该程序应该允许用户将骑士放到任何一个起始正方形&#xff0c;并单击Solve按钮&#xff0c;用动画展示骑士沿着路径的移动&…

2024年信息安全企业CRM选型与应用研究报告

数字化的生活给人们带来便利的同时也带来一定的信息安全隐患&#xff0c;如网络侵权、泄露用户隐私、黑客攻击等。在互联网高度发展的今天&#xff0c;信息安全与我们每个人、每个组织甚至每个国家都息息相关。 信息安全行业蓬勃发展。根据智研咨询数据&#xff0c;2021年&…

3DMAX乐高建筑生成器插件LegoBuilding使用方法详解

3DMAX乐高建筑生成器插件LegoBuilding使用教程 3DMAX乐高建筑生成器插件LegoBuilding&#xff0c;一键批量生成随机的乐高积木样式建筑群&#xff0c;可作为配景楼建模使用。可根据闭合样条线画定范围或地形&#xff08;网格&#xff09;对象表面范围和起伏批量生成随机形状的乐…

深入理解音视频pts,dts,time_base以及时间数学公式

引入 首先介绍一下基础名词 DTS&#xff08;Decoding Time Stamp&#xff09;&#xff1a;即解码时间戳&#xff0c;这个时间戳的意义在于告诉播放器该在什么时候解码这一帧的数据。当数据没b帧时&#xff0c;dts pts&#xff0c;有兴趣可参阅我前面视频知识类文章。 PTS&a…

MyBatis - 动态SQL

前言 我们在某网站填写个人信息时&#xff0c;时常会遇到可以选填的空&#xff08;即可填&#xff0c;可不填&#xff09;&#xff0c;由于之前讲过的Java中的SQL语句都是固定的&#xff0c;且我们不可能对所有情况都写出与之对应的插入语句&#xff08;太过繁琐&#xff09;&…

虚幻引擎的三种输入模式和将控件显示到屏幕上

首先要知道一个概念 , HUD 和 Input 都是由 PlayerController 来控制的 而虚幻的Input控制模式有三种 Set Input Mode Game Only (设置输入模式仅限游戏): 视角会跟着鼠标旋转 , 就是正常游戏的模式 , 这也是游戏默认输入模式 Set Input Mode UI Only (设置输入模式仅限UI): …

【操作系统强化】王道强化一轮笔记

第一章 计算机系统概述 考点1 操作系统的概念、特征和功能 1. 2. 考点2 内核态与用户态 1. 2.用户态和内核态之间的切换本质上就是应用程序和操作系统对CPU控制器的切换 考点3 中断和异常 1. 2. 考点4 系统调用 1. 2. 3.C 考点5 操作系统引导 1. 2. ①磁盘的物理格式化&…

APP自动化中 ADB Monkey用法

一、monkey是干什么的&#xff1f; 我们可以使用monkey做手机端性能的压力测试&#xff0c;稳定性测试 二、monkey在使用的时候&#xff0c;他的运行特性 monkey默认配置下执行&#xff0c;会在手机中随机的点击或者轻触我们的手机中应用&#xff0c;不过这个时候&#xff0…

在Windows系统上安装的 flatbuffers C++ 库

步骤一 下载:https://github.com/google/flatbuffers git clone gitgithub.com:google/flatbuffers.git步骤二 打开安装目录,然后再打开该目录下的powershell, 新建build目录 cd build cmake ..步骤三 进入步骤二生成的build目录里面,点击FlatBuffers.sln,打开vs2019 补充…

信息安全工程师(13)网络攻击一般过程

前言 网络攻击的一般过程是一个复杂且系统化的行为&#xff0c;其目标往往在于未经授权地访问、破坏或窃取目标系统的信息。 一、侦查与信息收集阶段 开放源情报收集&#xff1a;攻击者首先会通过搜索引擎、社交媒体、论坛等公开渠道获取目标的基本信息&#xff0c;如姓名、地址…

【经验分享】电商api接口——各类商品数据一键获取

目前&#xff0c;双十一促销活动正在火爆预热进行中。大促期间&#xff0c;消费者常常会做攻略以防被坑&#xff0c;而活动期间&#xff0c;品牌商家方也需要有所行动&#xff0c;避免一些不必要的损失。 大促期间&#xff0c;商家前前后后的改价活动往往比较频繁&#xff0c;…

超分之SPIN

Lightweight image super-resolution with superpixel token interaction[C]利用超像素token交互实现轻量级图像超分辨率Zhang A, Ren W, Liu Y, et al.Proceedings of the IEEE/CVF International Conference on Computer Vision. 2023: 12728-12737. 文章目录 摘要1. 引言2. …

【开源免费】基于SpringBoot+Vue.JS体育馆管理系统(JAVA毕业设计)

本文项目编号 T 048 &#xff0c;文末自助获取源码 \color{red}{T048&#xff0c;文末自助获取源码} T048&#xff0c;文末自助获取源码 目录 一、系统介绍二、演示录屏三、启动教程四、功能截图五、文案资料5.1 选题背景5.2 国内外研究现状5.3 可行性分析5.4 用例设计 六、核…

元器件数据手册识别工具

数据手册识别方案&#xff0c;目前有多家厂商实现了这个功能&#xff0c;分别采用不同的技术路线实现。 基于AI方法&#xff1a;使用大量的数据手册进行训练&#xff0c;训练后的将模型文件提供给客户&#xff0c;用户在程序中加载模型文件和数据手册得到手册里面的数据结果。 …

Python中requests模块(爬虫)基本使用

Python的requests模块是一个非常流行的HTTP库&#xff0c;用于发送HTTP/1.1请求。 一、模块导入 1、requests模块的下载&#xff1a; 使用包管理器下载&#xff0c;在cmd窗口&#xff0c;或者在项目的虚拟环境目录下&#xff1a; pip3 install -i https://pypi.tuna.tsingh…

JUC高并发编程1:JUC概述

1 什么是JUC 1.1 JUC简介 JUC就是 java.util .concurrent 工具包的简称。这是一个处理线程的工具包&#xff0c;JDK 1.5 开始出现的。 1.2 进程与线程 进程&#xff08;Process&#xff09;和线程&#xff08;Thread&#xff09;是操作系统中用于实现多任务处理的两种基本概…

Linux 基本指令的学习

01. ls 指令 语法 &#xff1a; ls [ 选项 ][ 目录或文件 ] 功能 &#xff1a;对于目录&#xff0c;该命令列出该目录下的所有子目录与文件。对于文件&#xff0c;将列出文件名以及其他信息。 常用选项&#xff1a; -a 列出目录下的所有文件&#xff0c;包括以 . 开头的隐含…

计算机二级C语言疑难

1.strcpy函数 在C语言中strcpy&#xff08;&#xff09;函数会将字符串2&#xff08;包括字符串结束字符/0&#xff09;的函数覆盖到字符串1&#xff0c;如果字符串1没有足够的空间容纳字符串会导致缓冲溢出的错误 例题&#xff1a;程序设计 规定输入的字符串中只包含字母和…