0

0

SpringBoot怎么配置跨域过滤器允许跨域访问

王林

王林

发布时间:2023-05-10 15:52:27

|

1810人浏览过

|

来源于亿速云

转载

SpringBoot跨域过滤器配置允许跨域访问

跨域请求

当一个资源从与该资源本身所在的服务器不同的域或端口请求一个资源时,资源会发起一个跨域 http 请求。

出于安全原因,浏览器限制从脚本内发起的跨源HTTP请求。 例如,XMLHttpRequest和Fetch API遵循同源策略。 这意味着使用这些API的Web应用程序只能从加载应用程序的同一个域请求HTTP资源,除非使用CORS头文件。

问题背景

如果前端提示”Access-Control-Allow-Origin”问题

XMLHttpRequest cannot load http://xxxxxxxxxx/. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'null' is therefore not allowed access.

跨域过滤器

那么需要再SpringBoot2配置跨域过滤器允许跨域访问。

import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.stereotype.Component;
@Component  
public class CorsFilter implements Filter {  
    @Override
    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {  
        HttpServletRequest request = (HttpServletRequest) req;
        HttpServletResponse response = (HttpServletResponse) res;  
        response.setHeader("Access-Control-Allow-Origin", "*");  
        response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE, PUT, GET");  
        response.setHeader("Access-Control-Max-Age", "3600");  
        response.setHeader("Access-Control-Allow-Headers", "x-requested-with");  
        chain.doFilter(req, res);  
    }  
    @Override
    public void init(FilterConfig filterConfig) {}  
    @Override
    public void destroy() {}  
}

跨域功能改进

如果需要显示跨域地址,还可以在里面加上访问来源打印语句,供排查

String curOrigin = request.getHeader("Origin");
System.out.println("###跨域过滤器->当前访问来源->"+curOrigin+"###");

如果需要跨域权限,可以判断一下来源

String curOrigin = request.getHeader("Origin");
System.out.println("###跨域过滤器->当前访问来源->"+curOrigin+"###");  
if(curOrigin.indexOf("127.0.0.1:8080")>-1){
    response.setHeader("Access-Control-Allow-Origin", "*");
}

SpringBoot跨域设置(CORS)

一、什么是跨域

请求url的协议、域名、端口三者有任意一个不同即为跨域。跨域问题是因为浏览器的同源策略的限制而产生的。

  • 同源:请求url的协议、域名、端口三者都相同即为同源(同一个域)。

  • 同源策略:同源策略(Sameoriginpolicy)是一种约定,他是浏览器最核心也最基本的安全功能。同源策略会阻止非同源(同一个域)的内容进行交互。

同源策略的限制:

  • 无法读取非同源网页的Cookie、LocalStorage和IndexedDB

  • 无法接触非同源网页的DOM

  • 无法向非同源地址发送AJAX请求

浏览器的同源策略会限制跨域请求,限制的方式一般有两种:

  • 浏览器限制发起跨域请求;

  • 跨域请求可以正常发起,但是返回的结果被浏览器拦截了。

一般浏览器都是第二种方式限制跨域请求,那就是说请求已到达服务器,并有可能对数据库里的数据进行了操作,但是返回的结果被浏览器拦截了,那么我们就获取不到返回结果,这是一次失败的请求,但是可能对数据库里的数据产生了影响。

为了防止这种情况的发生,规范要求,对这种可能对服务器数据产生副作用的HTTP请求方法,浏览器必须先使用OPTIONS方法发起一个预检请求,从而获知服务器是否允许该跨域请求:如果允许,就发送带数据的真实请求;如果不允许,则阻止发送带数据的真实请求。

二、跨域资源共享(CORS)

解决非同源内容无法交互的问题,目前主流的解决方案就是:CORS(跨域资源共享)。

跨域资源共享(Cross-origin Resource Sharing)简称CORS,它突破了一个请求在浏览器发出只能在同源的情况下向服务器获取数据的限制。

CORS约定服务器端和浏览器在HTTP协议之上,通过一些额外HTTP头部信息,进行跨域资源共享的协商。服务器端和浏览器都必需遵循规范中的要求。

CORS把HTTP的跨域请求分成两类,简单请求和非简单请求,不同请求按照不同的策略进行跨域资源共享协商。

1. 简单请求

简单跨域请求需满足的条件:

1.请求方法是GET、HEAD或者POST(POST时,Content-Type的值必须是application/x-www-form-urlencoded、multipart/form-data、text/plain中的一个值);

2.请求中没有自定义HTTP请求头。

HTTP头只能时下面这些字段:

  • Accept

  • Accept-Language

  • Content-Language

  • DPR

  • Downlink

  • Save-Data

  • Viewport-Width

  • Width

  • Content-Type

以上两点都满足才是简单跨域请求。

对于简单跨域请求,处理方式如下:

1.浏览器要做的就是在HTTP请求头中添加Origin,将JavaScript脚本所在域填充进去,向其他域的服务器请求资源。

Napkin AI
Napkin AI

Napkin AI 可以将您的文本转换为图表、流程图、信息图、思维导图视觉效果,以便快速有效地分享您的想法。

下载
Origin: http://www.joker.com

Origin字段用来说明,本次请求来自哪个源(协议 + 域名 + 端口)。服务器根据这个值,决定是否同意这次请求。

2.服务器端收到一个简单跨域请求后,根据资源权限配置,在响应头中添加Access-Control-Allow-Origin。

如果Origin指定的源,不在许可范围内,服务器会返回一个正常的HTTP回应。 但这个响应头信息没有包含Access-Control-Allow-Origin字段,浏览器就知道该域名不在许可范围内。

如果Origin指定的域名在许可范围内,服务器返回的响应,会多出几个头信息字段:

Access-Control-Allow-Origin: http://www.joker.com
Access-Control-Allow-Credentials: true
Access-Control-Expose-Headers: My-Token
  • Access-Control-Allow-Origin:该字段是必须的。它的值要么是请求时Origin字段的值,要么是一个*值,表示接受任意域名的请求。

  • Access-Control-Allow-Credentials: 该字段是可选的。它的值是一个布尔值,表示是否允许发送Cookie。默认情况下,Cookie不包括在CORS请求之中。设为true,即表示服务器明确许可,Cookie可以包含在请求中,一起发给服务器。这个值也只能设为true,如果服务器不要浏览器发送Cookie,删除该字段即可。

  • Access-Control-Expose-Headers:该字段是可选的。CORS请求时,XMLHttpRequest对象的getResponseHeader()方法只能拿到6个基本字段:Cache-Control、Content-Language、Content-Type、Expires、Last-Modified、Pragma。如果想拿到其他字段,就必须在Access-Control-Expose-Headers里面指定。

3.浏览器收到响应后,通过获取响应头中的Access-Control-Allow-Origin字段,来判断如果当前域已经得到授权,则将结果返回给JavaScript。否则浏览器忽略此次响应。

2. 非简单请求

非简单跨域请求需满足的条件:

  • 除GET、HEAD和POST(Content-Type的值是:application/x-www-form-urlencoded、multipart/form-data、text/plain中的一个值)以外的其他HTTP方法

  • 如:PUT、DELETE、TRACE、PATCH、POST(Content-Type的值是:application/json)。

  • 请求中有自定义HTTP头部。

以上两点只要至少满足其中一点就是非简单跨域请求。

对于非简单跨域请求,处理方式如下:

1.浏览器在发送真实HTTP请求之前先发送一个OPTIONS的预检请求,检测服务器端是否支持真实请求进行跨域资源访问。

真实请求的信息在OPTIONS请求中通过请求头中的Access-Control-Request-Method和Access-Control-Request-Headers字段来描述。此外与简单跨域请求一样,请求头中也会有Origin字段。

Origin: http://www.joker.com
Access-Control-Request-Method: PUT
Access-Control-Request-Headers: Header1,Header2
  • Origin:必须字段,用于指定请求源。

  • Access-Control-Request-Method:必须字段,用于描述真实请求的方法(PUT、DELETE等)。

  • Access-Control-Request-Headers:指定真实请求会额外发送的请求头字段信息。

2.服务器端接到预检请求后,会检查了Origin、Access-Control-Request-Method和Access-Control-Request-Headers字段,检验是否允许跨源请求。

如果不允许该跨域请求,会返回一个正常的HTTP回应,但这个响应头信息没有包含Access-Control-Allow-Origin字段,浏览器就知道该域名不在许可范围内。

如果允许该跨域请求,就会在响应头中放入Access-Control-Allow-Origin、Access-Control-Allow-Methods和Access-Control-Allow-Headers,分别表示允许跨域资源请求的域、请求方法和请求头。此外,服务器端还可以在响应头中放入Access-Control-Max-Age,允许浏览器在指定时间内,无需再发送预检请求进行协商,直接用本次协商结果即可。

Access-Control-Allow-Origin: http://www.joker.com
Access-Control-Allow-Methods: GET, POST, PUT
Access-Control-Allow-Headers: Header1,Header2,Header3
Access-Control-Allow-Credentials: true
Access-Control-Max-Age: 1728000
  • Access-Control-Allow-Methods:该字段必需,它的值是逗号分隔的一个字符串,表明服务器支持的所有跨域请求的方法。注意,返回的是所有支持的方法,而不单是浏览器请求的那个方法。这是为了避免多次"预检"请求。

  • Access-Control-Allow-Headers:如果浏览器请求包括Access-Control-Request-Headers字段,则Access-Control-Allow-Headers字段是必需的。它也是一个逗号分隔的字符串,表明服务器支持的所有头信息字段,不限于浏览器在"预检"中请求的字段。

  • Access-Control-Allow-Credentials: 该字段与简单请求时的含义相同。它的值是一个布尔值,表示是否允许发送Cookie。默认情况下,Cookie不包括在CORS请求之中。设为true,即表示服务器明确许可,Cookie可以包含在请求中,一起发给服务器。这个值也只能设为true,如果服务器不要浏览器发送Cookie,删除该字段即可。

  • Access-Control-Max-Age: 该字段可选,用来指定本次预检请求的有效期,单位为秒。上面结果中,有效期是20天(1728000秒),即允许缓存该条回应1728000秒(即20天),在此期间,不用发出另一条预检请求。

浏览器根据OPTIONS请求返回的结果来决定是否继续发送真实的请求进行跨域资源访问。这个过程对真实请求的调用者来说是透明的。

三、SpringBoot设置CORS

SpringBoot设置CORS的的本质都是通过设置响应头信息来告诉前端该请求是否支持跨域。

SpringBoot设置CORS的方式主要有以下三种。

1. 配置过滤器CorsFilter

@Configuration
public class CorsConfig {
    
    @Bean
    CorsFilter corsFilter() {
        CorsConfiguration configuration = new CorsConfiguration();
        configuration.setAllowedOrigins(Arrays.asList("*"));
        configuration.setAllowedMethods(Arrays.asList("*"));
        configuration.setAllowedHeaders(Arrays.asList("*"));
        configuration.setAllowCredentials(true);
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration("/**", configuration);
        return new CorsFilter(source);
    }
}

2. 实现接口WebMvcConfigurer

@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
    
    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**")
                .allowedOrigins("*")
                .allowedHeaders("*")
                .allowedMethods("*")
                .allowCredentials(true);
    }
}

3. 使用注解@CrossOrigin

@CrossOrigin注解可以用在类或者方法上

用在控制器类上,表示 该类的所有方法都允许跨域

@RestController
@CrossOrigin
public class TestController {
    
    @GetMapping("test")
    public String test() {
        return "success";
    }
}

用在控制器方法上,表示该方法都允许跨域

@RestController
public class TestController {
    @CrossOrigin
    @GetMapping("test")
    public String test() {
        return "success";
    }
}

@CrossOrigin注解源码

@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface CrossOrigin {
  
  /**
   * 这origins和value是一样的
   * 允许来源域名的列表,例如 www.baidu.com,匹配的域名是跨域预请求Response头中的Access-Control-Aloow_origin字段值。
   * 不设置确切值时默认支持所有域名跨域访问。
   */
  @AliasFor("origins")
  String[] value() default {};
  @AliasFor("value")
  String[] origins() default {};
  /**
   * 高版本下Spring2.4.4使用originPatterns而不是value和origins
   */
  String[] originPatterns() default {};
  /**
   * 跨域请求中允许的请求头中的字段类型, 该值对应跨域预请求Response头中的Access-Control-Allow-Headers字段值。
   * 不设置确切值默认支持所有的header字段(Cache-Controller、Content-Language、Content-Type、Expires、Last-Modified、Pragma)跨域访问
   */
  String[] allowedHeaders() default {};
  /**
   * 跨域请求请求头中允许携带的除Cache-Controller、Content-Language、Content-Type、Expires、Last-Modified、Pragma这六个基本字段之外的其他字段信息,
   * 对应的是跨域请求Response头中的Access-control-Expose-Headers字段值
   */
  String[] exposedHeaders() default {};
  /**
   * 跨域HTTP请求中支持的HTTP请求类型(GET、POST...),
   * 不指定确切值时默认与 Controller 方法中的 methods 字段保持一致。
   */
  RequestMethod[] methods() default {};
  /**
   * 浏览器是否将本域名下的cookie信息携带至跨域服务器中。默认携带至跨域服务器中,但要实现cookie共享还需要前端在AJAX请求中打开withCredentials属性。
   * 该值对应的是是跨域请求 Response 头中的 'Access-Control-Allow-Credentials' 字段值。
   */
  String allowCredentials() default "";
  /**
   * 该值的目的是减少浏览器预检请求/响应交互的数量。默认值1800s。设置了该值后,浏览器将在设置值的时间段内对该跨域请求不再发起预请求。
   * 该值对应的是是跨域请求Response头中的Access-Control-Max-Age字段值,表示预检请求响应的缓存持续的最大时间。
   */
  long maxAge() default -1;
}

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

WorkBuddy
WorkBuddy

腾讯云推出的AI原生桌面智能体工作台

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
json数据格式
json数据格式

JSON是一种轻量级的数据交换格式。本专题为大家带来json数据格式相关文章,帮助大家解决问题。

457

2023.08.07

json是什么
json是什么

JSON是一种轻量级的数据交换格式,具有简洁、易读、跨平台和语言的特点,JSON数据是通过键值对的方式进行组织,其中键是字符串,值可以是字符串、数值、布尔值、数组、对象或者null,在Web开发、数据交换和配置文件等方面得到广泛应用。本专题为大家提供json相关的文章、下载、课程内容,供大家免费下载体验。

549

2023.08.23

jquery怎么操作json
jquery怎么操作json

操作的方法有:1、“$.parseJSON(jsonString)”2、“$.getJSON(url, data, success)”;3、“$.each(obj, callback)”;4、“$.ajax()”。更多jquery怎么操作json的详细内容,可以访问本专题下面的文章。

337

2023.10.13

go语言处理json数据方法
go语言处理json数据方法

本专题整合了go语言中处理json数据方法,阅读专题下面的文章了解更多详细内容。

82

2025.09.10

ajax教程
ajax教程

php中文网为大家带来ajax教程合集,Ajax是一种用于创建快速动态网页的技术。通过在后台与服务器进行少量数据交换,Ajax可以使网页实现异步更新。这意味着可以在不重新加载整个网页的情况下,对网页的某部分进行更新。php中文网还为大家带来ajax的相关下载资源、相关课程以及相关文章等内容,供大家免费下载使用。

166

2023.06.14

ajax中文乱码解决方法
ajax中文乱码解决方法

ajax中文乱码解决方法有设置请求头部的字符编码、在服务器端设置响应头部的字符编码和使用encodeURIComponent对中文进行编码。本专题为大家提供ajax中文乱码相关的文章、下载、课程内容,供大家免费下载体验。

170

2023.08.31

ajax传递中文乱码怎么办
ajax传递中文乱码怎么办

ajax传递中文乱码的解决办法:1、设置统一的编码方式;2、服务器端编码;3、客户端解码;4、设置HTTP响应头;5、使用JSON格式。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

124

2023.11.15

ajax网站有哪些
ajax网站有哪些

使用ajax的网站有谷歌、维基百科、脸书、纽约时报、亚马逊、stackoverflow、twitter、hacker news、shopify和basecamp等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

260

2024.09.24

TypeScript类型系统进阶与大型前端项目实践
TypeScript类型系统进阶与大型前端项目实践

本专题围绕 TypeScript 在大型前端项目中的应用展开,深入讲解类型系统设计与工程化开发方法。内容包括泛型与高级类型、类型推断机制、声明文件编写、模块化结构设计以及代码规范管理。通过真实项目案例分析,帮助开发者构建类型安全、结构清晰、易维护的前端工程体系,提高团队协作效率与代码质量。

26

2026.03.13

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Redis6入门到精通超详细教程
Redis6入门到精通超详细教程

共47课时 | 5.6万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号