cors 前后端分离跨域问题_SpringBoot 实现前后端分离的跨域访问(CORS)

序言:跨域资源共享向来都是热门的需求,使用CORS可以帮助我们快速实现跨域访问,只需在服务端进行授权即可,无需在前端添加额外设置,比传统的JSONP跨域更安全和便捷。

一、基本介绍

简单来说,CORS是一种访问机制,英文全称是Cross-Origin Resource Sharing,即我们常说的跨域资源共享,通过在服务器端设置响应头,把发起跨域的原始域名添加到Access-Control-Allow-Origin 即可。

1. CORS工作原理

CORS实现跨域访问并不是一蹴而就的,需要借助浏览器的支持,从原理题图我们可以清楚看到,简单的请求(通常指GET/POST/HEAD方式,并没有去增加额外的请求头信息)直接创建了跨域请求的XHR对象,而复杂的请求则要求先发送一个"预检"请求,待服务器批准后才能真正发起跨域访问请求。

来自维基百科

根据官方文档W3C规范-CORS 的描述,目前CORS使用了如下头部信息:

2. Request Headers(请求头)

温馨提示:Request Headers 无需人为干预,因为浏览器会自动识别跨域请求并添加对应的请求头。

Origin 表示发起跨域请求的原始域。

Access-Control-Request-Method 表示发起跨域请求的方式,例如GET/POST。

Access-Control-Request-Headers表示发起跨域请求的额外头信息。

3. Response headers(响应头 )

温馨提示:Response Headers 需要人为干预,通过设置响应头以帮助服务器资源进行跨域授权,例如允许哪些原始域进行跨域请求,是否允许响应信息携带Cookie等认证信息。

Access-Control-Allow-Origin 表示允许哪些原始域进行跨域访问。

Access-Control-Allow-Credentials表示是否允许客户端获取用户凭据。

使用场景:例如现在需要登录系统后才能发起跨域请求,并且要附带Cookie信息给服务器。则必须具备两个条件:1. 浏览器端:发送AJAX请求前需设置通信对象XHR的withCredentials 属性为true。 2.服务器端:设置Access-Control-Allow-Credentials为true。两个条件缺一不可,否则即使服务器同意发送Cookie,浏览器也无法获取。正确姿势如下:

$.ajax({

url: 'localhost:8080',

xhrFields: {

withCredentials: true //表示发起跨域访问并要求携带Cookie等认证信息

},

success: function (r) {

console.log(r)

}

});

有好奇的小伙伴可能会问为什么在W3C手册中找不到跨域属性xhrFields的描述,因为该属性并不是通信对象XHR的默认属性,而是自定义属性,所以在jQuery Ajax 参考手册 中并没有明确注明,但我们可以在jQuery源码中找到这段蛛丝马迹,那么整体思路就很清晰了。

// Cross domain only allowed if supported through XMLHttpRequest

if ( support.cors || xhrSupported && !options.crossDomain ) {

return {

send: function( headers, complete ) {

var i,

xhr = options.xhr();

xhr.open(

options.type,

options.url,

options.async,

options.username,

options.password

);

// Apply custom fields if provided

if ( options.xhrFields ) {

for ( i in options.xhrFields ) {

xhr[ i ] = options.xhrFields[ i ];

}

}

...

}

Access-Control-Allow-Methods 表示允许哪些跨域请求的提交方式。(例如GET/POST)

Access-Control-Allow-Headers 表示跨域请求的头部的允许范围。

Access-Control-Expose-Headers 表示允许暴露哪些头部信息给客户端。

使用说明:基于安全考虑,如果没有设置额外的暴露,跨域的通信对象XMLHttpRequest只能获取标准的头部信息。

Access-Control-Max-Age 表示预检请求 [Preflight Request] 的最大缓存时间。

二、CORS实现跨域访问

授权方式

方式1:返回新的CorsFilter

方式2:重写WebMvcConfigurer

方式3:使用注解(@CrossOrigin)

方式4:手工设置响应头(HttpServletResponse )

注:CorsFilter / WebMvcConfigurer / @CrossOrigin 需要SpringMVC 4.2 以上的版本才支持,对应SpringBoot 1.3 版本以上都支持这些CORS特性。不过,使用SpringMVC4.2 以下版本的小伙伴也不用慌,直接使用方式4通过手工添加响应头来授权CORS跨域访问也是可以的。附:在SpringBoot 1.2.8 + SpringMVC 4.1.9 亲测成功。

注:方式1和方式2属于全局CORS配置,方式3和方式4属于局部CORS配置。如果使用了局部跨域是会覆盖全局跨域的规则,所以可以通过@CrossOrigin注解来进行细粒度更高的跨域资源控制。

1. 返回新的CorsFilter(全局跨域)

在任意配置类,返回一个新的CorsFilter Bean,并添加映射路径和具体的CORS配置信息。

package com.hehe.yyweb.config;

@Configuration

public class GlobalCorsConfig {

@Bean

public CorsFilter corsFilter() {

//1.添加CORS配置信息

CorsConfiguration config = new CorsConfiguration();

//放行哪些原始域

config.addAllowedOrigin("*");

//是否发送Cookie信息

config.setAllowCredentials(true);

//放行哪些原始域(请求方式)

config.addAllowedMethod("*");

//放行哪些原始域(头部信息)

config.addAllowedHeader("*");

//暴露哪些头部信息(因为跨域访问默认不能获取全部头部信息)

config.addExposedHeader("*");

//2.添加映射路径

UrlBasedCorsConfigurationSource configSource = new UrlBasedCorsConfigurationSource();

configSource.registerCorsConfiguration("/**", config);

//3.返回新的CorsFilter.

return new CorsFilter(configSource);

}

}

2. 重写WebMvcConfigurer(全局跨域)

在任意配置类,返回一个新的WebMvcConfigurer Bean,并重写其提供的跨域请求处理的接口,目的是添加映射路径和具体的CORS配置信息。

package com.hehe.yyweb.config;

@Configuration

public class GlobalCorsConfig {

@Bean

public WebMvcConfigurer corsConfigurer() {

return new WebMvcConfigurer() {

@Override

//重写父类提供的跨域请求处理的接口

public void addCorsMappings(CorsRegistry registry) {

//添加映射路径

registry.addMapping("/**")

//放行哪些原始域

.allowedOrigins("*")

//是否发送Cookie信息

.allowCredentials(true)

//放行哪些原始域(请求方式)

.allowedMethods("GET","POST", "PUT", "DELETE")

//放行哪些原始域(头部信息)

.allowedHeaders("*")

//暴露哪些头部信息(因为跨域访问默认不能获取全部头部信息)

.exposedHeaders("Header1", "Header2");

}

};

}

}

3. 使用注解(局部跨域)

在方法上(@RequestMapping)使用注解 @CrossOrigin :

@RequestMapping("/hello")

@ResponseBody

@CrossOrigin("http://localhost:8080")

public String index( ){

return "Hello World";

}

或者在控制器(@Controller)上使用注解 @CrossOrigin :

@Controller

@CrossOrigin(origins = "http://xx-domain.com", maxAge = 3600)

public class AccountController {

@RequestMapping("/hello")

@ResponseBody

public String index( ){

return "Hello World";

}

}

4. 手工设置响应头(局部跨域 )

使用HttpServletResponse对象添加响应头(Access-Control-Allow-Origin)来授权原始域,这里Origin的值也可以设置为"*" ,表示全部放行。

@RequestMapping("/hello")

@ResponseBody

public String index(HttpServletResponse response){

response.addHeader("Access-Control-Allow-Origin", "http://localhost:8080");

return "Hello World";

}

三、测试跨域访问

首先使用Spring Initializr 快速构建一个Maven工程,什么都不用改,在static目录下,添加一个页面:index.html 来模拟跨域访问。目标地址: http://localhost:8090/hello

Page Index

前台系统

$.ajax({

url: 'http://localhost:8090/hello',

type: "POST",

xhrFields: {

withCredentials: true //允许跨域认证

},

success: function (data) {

$("#info").html("跨域访问成功:"+data);

},

error: function (data) {

$("#info").html("跨域失败!!");

}

})

然后创建另一个工程,在Root Package添加Config目录并创建配置类来开启全局CORS。

package com.hehe.yyweb.config;

@Configuration

public class GlobalCorsConfig {

@Bean

public WebMvcConfigurer corsConfigurer() {

return new WebMvcConfigurer() {

@Override

public void addCorsMappings(CorsRegistry registry) {

registry.addMapping("/**");

}

};

}

}

接着,简单编写一个Rest接口 ,并指定应用端口为8090。

package com.hehe.yyweb;

@SpringBootApplication

@RestController

public class YyWebApplication {

@Bean

public TomcatServletWebServerFactory tomcat() {

TomcatServletWebServerFactory tomcatFactory = new TomcatServletWebServerFactory();

tomcatFactory.setPort(8090); //默认启动8090端口

return tomcatFactory;

}

@RequestMapping("/hello")

public String index() {

return "Hello World";

}

public static void main(String[] args) {

SpringApplication.run(YyWebApplication.class, args);

}

}

最后分别启动两个应用,然后在浏览器访问:http://localhost:8080/index.html ,可以正常接收JSON数据,说明跨域访问成功!!

尝试把全局CORS关闭,或者没有单独在方法或类上授权跨域,再次访问:http://localhost:8080/index.html 时会看到跨域请求失败!!

四、源码和文档

五、版权声明

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

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

相关文章

机器视觉中彩色成像必须考虑的十个问题

来源:Imagination Tech在为你的产品开发最适合的机器视觉系统时,需要考虑很多因素,以下列出开发过程中需要考虑的一些问题:颜色准确性/差异化首先要考虑的是应用程序所需的颜色精度和差异程度。在某些应用中,机器视觉相…

彩色的砖块

小易有一些彩色的砖块。每种颜色由一个大写字母表示。各个颜色砖块看起来都完全一样。现在有一个给定的字符串s,s中每个字符代表小易的某个砖块的颜色。小易想把他所有的砖块排成一行。如果最多存在一对不同颜色的相邻砖块,那么这行砖块就很漂亮的。请你帮助小易计算有多少种方…

linux 6.5桌面环境kde,CentOS 5/6 安装 GNOME 或 KDE 桌面

1、安装 XWindowyum-ygroupinstallXWindowSystem2.1、Centos 5.x 安装 GNOME 或 KDE (可择一安装)GNOMEyum-ygroupinstallGNOMEDesktopEnvironmentKDEyum-ygroupinstallKDE(KDesktopEnvironment)2.2、Centos 6.x 安装 GNOME 或 KDE (可择一安装)GNOMEyum-ygroupinstallDesktopK…

Zabbix的简单使用

0. 卸载mariadb 安装mysql 方法 rpm -qa |grep mariadb 然后 rpm -e --nodeps mariadb***** 安装mysql # 下载mysql源安装包 shell> wget http://dev.mysql.com/get/mysql57-community-release-el7-8.noarch.rpm # 安装mysql源 shell> yum localinstall mysql57-communi…

嫦娥“挖土”归来有多难?看看中国首颗返回式卫星的故事

本文转载自“科技日报(kjrbwx)”,原标题《嫦娥“挖土”归来有多难?看看中国首颗返回式卫星的故事》,作者 | 吕炳宏 付毅飞2020年11月30日,嫦娥五号探测器在环月轨道上,成功实施着陆器上升器组合…

springboot 添加拦截器之后中文乱码_spring boot 2.x 添加拦截器配置未生效的问题

背景: 今天有一个需求需要拦截除登录相关请求以外的所有请求,并查看request 中是否包含指定的信息,而自然就想到了使用拦截器就可以轻松实现编写拦截器,获取请求头信息中的test,并打印出来Componentpublic class Autho…

等差数列

[编程题] 等差数列时间限制:1秒空间限制:32768K如果一个数列S满足对于所有的合法的i,都有S[i 1] S[i] d, 这里的d也可以是负数和零,我们就称数列S为等差数列。小易现在有一个长度为n的数列x,小易想把x变为一个等差数列。小易允许在数列上做交换任意两…

179.【2023年华为OD机试真题(C卷)】最大坐标值(模拟实现JavaPythonC++JS)

请到本专栏顶置查阅最新的华为OD机试宝典 点击跳转到本专栏-算法之翼:华为OD机试 🚀你的旅程将在这里启航!本专栏所有题目均包含优质解题思路,高质量解题代码,详细代码讲解,助你深入学习,深度掌握! 文章目录 179.【2023年华为OD机试真题(C卷)】最大坐标值(模拟…

2018 UESTC Training for Data Structures

Link A - 一棵简单的线段树 标准线段树 #include<bits/stdc.h> #define ll long long using namespace std;const int maxn 1e67;int n,q; struct node {int l,r,maxx,minx;ll num;ll sum; }t[maxn*4];void build(int x,int l,int r) {t[x].ll,t[x].rr;if(lr){t[x].numt…

linux下的驱动大小,(转)Linux驱动开发需要注意的点/KO大小/内存管理

1.不要想不通就写代码&#xff0c;不要为了存粹的解决问题而加代码&#xff0c;不要忽视任何一种场景可能&#xff0c;因为躲得了一时&#xff0c;躲不了一波&#xff0c;BUG迟早会被挖出来的&#xff0c;到时候更加苦逼。2.内存是个很严肃的问题&#xff0c;不要直接调用系统函…

重磅,2020年度第十届吴文俊人工智能科学技术奖获奖名单公示

来源&#xff1a;科奖圈根据《吴文俊人工智能科学技术奖励条例》和《吴文俊人工智能科学技术奖励实施细则》相关规定&#xff0c;经全国各地方人工智能学会、协会及联盟&#xff0c;各高校及科研&#xff08;院&#xff09;所&#xff0c;学会各专业委员会及工作委会&#xff0…

python封装exe 时间time问题_python模块之datetime

datetime模块简介在开发工作中&#xff0c;我们经常需要用到日期与时间&#xff0c;如&#xff1a;作为日志信息的内容输出计算某个功能的执行时间用日期命名一个日志文件的名称记录或展示某文章的发布或修改时间其他Python中提供了多个用于对日期和时间进行操作的内置模块&…

交错01串

[编程题] 交错01串时间限制&#xff1a;1秒空间限制&#xff1a;32768K如果一个01串任意两个相邻位置的字符都是不一样的,我们就叫这个01串为交错01串。例如: "1","10101","0101010"都是交错01串。小易现在有一个01串s,小易想找出一个最长的连续…

理解 %IOWAIT (%WIO)

%iowait 是 “sar -u” 等工具检查CPU使用率时显示的一个指标&#xff0c;在Linux上显示为 %iowait&#xff0c;在有的Unix版本上显示为 %wio&#xff0c;含义都是一样的。这个指标常常被误读&#xff0c;很多人把它当作I/O问题的征兆&#xff0c;我自己每隔一段时间就会遇到对…

linux系统安装显卡驱动卡顿,关于Ubuntu16.04上N卡驱动导致滚动屏幕卡顿问题

环境Ubuntu16.041080ti显卡问题屏幕显示正常&#xff0c;但是在打开网页或者进行跑深度学习程序的时候画面会发生一卡一下的情况&#xff0c;严重时出现类似于死机的情况。查看系统monitor并不显示显存和内存爆表&#xff0c;于是推断为nvidia显卡驱动不兼容的问题。解决更换显…

自由意志不存在?神经科学能证明不?

来源&#xff1a; 神经现实本文经授权摘自《认知科学对当代哲学的挑战》作者&#xff1a;李恒威神经科学能说明自由意志不存在吗?里贝特是人类意识和自由意志的实验研究领域的先驱性神经科学家&#xff0c;但驱使他开展意识的实证研究的根本动因是回应意识科学研究中的本体论问…

操作序列

[编程题] 操作序列时间限制&#xff1a;2秒空间限制&#xff1a;32768K小易有一个长度为n的整数序列,a_1,...,a_n。然后考虑在一个空序列b上进行n次以下操作:1、将a_i放入b序列的末尾2、逆置b序列小易需要你计算输出操作n次之后的b序列。 输入描述:输入包括两行,第一行包括一个…

南方cass怎么添加指北针_添加比例尺 指北针

添加图例、比例尺、指北针代码中有注释&#xff0c;直接上指北针C#代码publicvoidAddNorthArrow(IPageLayout pageLayout){IGraphicsContainer container pageLayoutasIGraphicsContainer;IActiveView activeView pageLayoutasIActiveView;//获得MapFrameIFrameE…

MySQL数据库order by 奇慢无比

今天遇到个奇葩的问题&#xff0c; sql 数据量很大 有where 和order by&#xff0c;不加order by 速度很快&#xff0c;加了就很慢 一、首先我们对这条sql执行查询计划&#xff1a; explain select t.order_id from book_order t ORDER BY t.order_id desc explain select t.…

独立的小易

[编程题] 独立的小易时间限制&#xff1a;1秒空间限制&#xff1a;32768K小易为了向他的父母表现他已经长大独立了,他决定搬出去自己居住一段时间。一个人生活增加了许多花费: 小易每天必须吃一个水果并且需要每天支付x元的房屋租金。当前小易手中已经有f个水果和d元钱,小易也能…