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

文章目录

  • 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 {@Beanpublic 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.xdnf.cn/news/149409.html

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

相关文章

【JavaEE】——内存可见性问题

阿华代码&#xff0c;不是逆风&#xff0c;就是我疯&#xff0c;你们的点赞收藏是我前进最大的动力&#xff01;&#xff01;希望本文内容能够帮助到你&#xff01; 目录 一&#xff1a;内存可见性问题 1&#xff1a;代码解释 2&#xff1a;结果分析 &#xff08;1&#xf…

分享开源且强大的HTML5网页视频播放器

随着互联网技术的飞速发展&#xff0c;视频内容已成为现代网络体验中不可或缺的一部分。无论是在线教育、娱乐还是企业宣传&#xff0c;高质量的视频播放器都是确保用户获得良好观看体验的关键。HTML5的出现极大地推动了网页视频播放技术的进步&#xff0c;逐渐取代了传统的Fla…

MySQL篇(日志)

目录 一、错误日志 二、二进制日志 1. 简介 2. 作用 3. 参数说明 3.1. 两个参数 3.2. 格式 3.3. 查看 3.4. 删除 4. 查询日志 三、慢查询日志 一、错误日志 错误日志是 MySQL 中最重要的日志之一&#xff0c;它记录了当 mysqld 启动和停止时&#xff0c; 以及服务器…

三菱FX5U PLC故障处理(各种出错的内容、原因及处理方法进行说明。)

对使用系统时发生的各种出错的内容、原因及处理方法进行说明。 故障排除的步骤 发生故障时&#xff0c;按以下顺序实施故障排除。 1.确认各模块是否正确安装或正确配线。 2、确认CPU模块的LED。 3.确认各智能功能模块的LED。(各模块的用户手册) 4、连接工程工具&#xff0c;启…

kubernetes网络(三)之bird的路由反射器的使用

一、摘要 上一篇文章中我们用 bird 程序实现了三台服务器之间的BGP full mesh。本文我们将实验把full mesh方式改为RR 路由反射器方式 &#xff0c;让宿主的BIRD相互学习到对方的容器网段&#xff0c;从而达到容器网段能相互通信的目的。 二、bird 实验 bird简介 BIRD 实际…

操作系统 | 学习笔记 | | 王道 | 5.3 磁盘和固态硬盘

5.3 磁盘和固态硬盘 5.3.1 磁盘 磁盘结构 磁盘&#xff1a;磁盘的表面由一些磁性物质组成&#xff0c;可以用这些磁性物质来记录二进制数据 磁道&#xff1a;磁盘的盘面被划分成一个个磁道。这样的一个“圈”就是一个磁道 扇区&#xff1a;一个磁道又被划分成一个个扇区&am…

828华为云征文 | 在华为云X实例上安装部署企业Wiki知识分享平台的实践

目录 前言 1. 华为云X实例介绍 1.1 华为云Flexus云服务概述 1.2 Flexus云服务器X实例的特点 2. MM-Wiki知识分享平台介绍 2.1 什么是MM-Wiki 2.2 MM-Wiki的功能特点 3. 安装部署环境 4. MM-Wiki安装部署步骤 4.1 下载与准备工作 4.2 安装MM-Wiki 4.3 启动与运行 5…

[spring]MyBatis介绍 及 用MyBatis操作简单数据库

文章目录 一. 什么是MyBatis二. MyBatis操作数据库步骤创建工程创建数据库创建对应实体类配置数据库连接字符串写持久层代码单元测试 三. MyBatis基础操作打印日志参数传递增删改查 四. MyBatis XML配置文件配置链接字符串和MyBatis写持久层代码方法定义Interface方法实现xml测…

从入门到精通:QT 100个关键技术关键词

Qt基础概念 Qt Framework - 一个跨平台的C图形用户界面应用程序开发框架。它不仅提供了丰富的GUI组件&#xff0c;还包括网络、数据库访问、多媒体支持等功能。 Qt Creator - Qt官方提供的集成开发环境&#xff08;IDE&#xff09;&#xff0c;集成了代码编辑器、项目管理工具、…

Linux网络之UDP与TCP协议详解

文章目录 UDP协议UDP协议数据报报头 TCP协议确认应答缓冲区 超时重传三次握手其他问题 四次挥手滑动窗口流量控制拥塞控制 UDP协议 前面我们只是说了UDP协议的用法,但是并没有涉及到UDP协议的原理 毕竟知道冰箱的用法和知道冰箱的原理是两个层级的事情 我们首先知道计算机网…

【RabbitMQ】RabbitMQ 的概念以及使用RabbitMQ编写生产者消费者代码

目录 1. RabbitMQ 核心概念 1.1生产者和消费者 1.2 Connection和Channel 1.3 Virtual host 1.4 Queue 1.5 Exchange 1.6 RabbitMO工作流程 2. AMQP 3.RabbitMO快速入门 3.1.引入依赖 3.2.编写生产者代码 ​3.3.编写消费者代码 4.源码 1. RabbitMQ 核心概念 在安装…

【Redis】Linux下安装配置及通过C++访问Redis

文章目录 一、Linux Centos 7.0版本下的安装及配置二、通过C访问Redis 一、Linux Centos 7.0版本下的安装及配置 通过源来安装&#xff0c;此次安装的版本为 redis 5.0 的&#xff0c;要通过其他源进行安装&#xff0c;首先安装 scl 源 yum install centos-release-scl-rh再安…

LED显示屏驱动电源:恒流与恒压,谁更胜一筹?

LED显示屏&#xff0c;作为现代电子显示技术的重要代表&#xff0c;已经在我们的生活中无处不在。无论是商场的广告牌、体育场的计分板&#xff0c;还是家庭中的智能电视&#xff0c;LED显示屏都以其鲜艳的色彩、高清晰度和长寿命赢得了我们的青睐。然而&#xff0c;在这背后&a…

爬虫逆向学习(七):补环境动态生成某数四代后缀MmEwMD

声明&#xff1a;本篇文章内容是整理并分享在学习网上各位大佬的优秀知识后的实战与踩坑记录 前言 这篇文章主要是研究如何动态生成后缀参数MmEwMD的&#xff0c;它是在文章爬虫逆向学习(六)&#xff1a;补环境过某数四代的基础上进行研究的&#xff0c;代码也是在它基础上增…

Python在AI中的应用--使用决策树进行文本分类

Python在AI中的应用--使用决策树进行文本分类 文本分类决策树什么是决策树 scikit算法 使用scikit的决策树进行文章分类一个文本分类的Python代码使用的scikit APIs说明装入数据集决策树算法类类构造器&#xff1a; 构造决策树分类器产生输出评估输出结果分类准确度分类文字评估…

如何从格式化的笔记本电脑或台式机中恢复照片

您想学习如何从已格式化的笔记本电脑或台式机中恢复已删除的照片吗&#xff1f;这篇文章解释了如何使用最佳格式的照片恢复软件来做到这一点。您可以通过简单的步骤格式化计算机后恢复已删除的图像。 将照片保存在笔记本电脑或 PC 硬盘上是很常见的。与相机存储卡和 USB 闪存驱…

代码随想录Day16 单调栈

739. 每日温度 该题的题意很简单 要求遍历温度数组 找出几天后会出现下一次更高的温度 这就可以用到单调栈的知识 通常是一维数组&#xff0c;要寻找任一个元素的右边或者左边第一个比自己大或者小的元素的位置&#xff0c;此时我们就要想到可以用单调栈了 那么我们该如何实现…

Leetcode 65. 有效数字

1.题目基本信息 1.1.题目描述 给定一个字符串 s &#xff0c;返回 s 是否是一个 有效数字。 例如&#xff0c;下面的都是有效数字&#xff1a;”2″, “0089”, “-0.1”, “3.14”, “4.”, “-.9”, “2e10”, “-90E3”, “3e7”, “6e-1”, “53.5e93”, “-123.456e789…

单链表:学生信息管理系统

一、头文件 #ifndef __LINK_H__ #define __LINK_H__ #include <myhead.h> #define MAX 30 // 建立学生结构体 typedef struct student {int id; //学号char name[20]; //姓名float score; //分数 }stu;typedef struct node {union{int len;stu data;};struct node * nex…

(Arxiv-2024)DiffLoRA:通过扩散生成个性化低秩自适应权重

DiffLoRA&#xff1a;通过扩散生成个性化低秩自适应权重 paper title&#xff1a;DiffLoRA: Generating Personalized Low-Rank Adaptation Weights with Diffusion paper是电子科技大学发表在arxiv 2024的工作 paper地址 Abstract 个性化文本转图像生成因其能够根据用户定义的…