Spring+JS前后端交互遇415/403错误,求解决方案
问题:Spring后端+JS前端应用的415与403错误处理
问题描述
开发了一个Spring后端+JS前端的应用,遇到两个核心问题:
- 前端通过jQuery发送POST请求提交用户数据,Postman中请求正常,但Spring后端返回
HttpMediaTypeNotSupportedException,提示不支持Content-Type 'text/plain;charset=UTF-8',前端报415错误; - 添加Spring Security配置后出现403错误,推测是拦截导致,不清楚新版本(WebSecurityConfigurerAdapter已废弃)中如何正确配置或临时禁用Spring Security。
相关代码如下:
前端JS请求代码
function addUserToDB() { origin='*'; let user = { "telephone": "+375296534488", "name": "Potemin", "password": ["p", "a", "s"], "passwordRetry": ["p", "a", "s"], "address": { "city": "New York", "street": "State", "houseNumber": 22 } }; $.post('http://localhost:8080/registration', user, data => {console.log(data)}) }
前端HTML代码
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Sign Up</title> <script src="js/registration.js"></script> <script src="https://code.jquery.com/jquery-3.7.0.js" integrity="sha256-JlqSTELeR4TLqP0OG9dxM7yDPqX1ox/HfgiSLBj8+kM=" crossorigin="anonymous"></script> </head> <body> <button onclick="addUserToDB()" id="b">button</button> </body> </html>
Spring Controller代码
package com.project.sushipizzabar.users.controllers; import com.project.sushipizzabar.users.UserService; import com.project.sushipizzabar.users.dto.userDto.UserCreateRequest; import com.project.sushipizzabar.users.dto.userDto.UserDto; import lombok.RequiredArgsConstructor; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import java.util.Arrays; @RestController @RequestMapping("/registration") @RequiredArgsConstructor public class RegistrationController { private final UserService service; @PostMapping public ResponseEntity<UserDto> addUser(@RequestBody UserCreateRequest userCreateRequest) { if (!Arrays.equals(userCreateRequest.getPassword(), userCreateRequest.getPasswordRetry())) { throw new IllegalArgumentException(); } return ResponseEntity.ok(service.findById(service.create(userCreateRequest))); } }
Spring Security配置代码
package com.project.sushipizzabar.config; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.security.config.Customizer; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.web.SecurityFilterChain; import org.springframework.web.cors.CorsConfiguration; import org.springframework.web.cors.CorsConfigurationSource; import org.springframework.web.cors.UrlBasedCorsConfigurationSource; import org.springframework.web.servlet.config.annotation.CorsRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; import java.util.List; @Configuration @EnableWebSecurity public class WebSecurityConfig implements WebMvcConfigurer { @Bean public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { http.csrf(Customizer.withDefaults()) .cors(Customizer.withDefaults()) .anonymous(Customizer.withDefaults()) .authorizeHttpRequests((authz) -> authz .requestMatchers("ttp://localhost:63342/").permitAll() ); return http.build(); } @Bean CorsConfigurationSource corsConfigurationSource() { CorsConfiguration configuration = new CorsConfiguration(); configuration.setAllowedOrigins(List.of("http://localhost:63342/")); configuration.setAllowedMethods(List.of("*")); configuration.setAllowedHeaders(List.of("*")); configuration.setAllowCredentials(true); UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); source.registerCorsConfiguration("/**", configuration); return source; } @Override public void addCorsMappings(CorsRegistry registry) { registry.addMapping("/registration") .allowedOrigins("http://localhost:63342/") .allowedMethods("GET", "POST") .allowedHeaders("*") .allowCredentials(true); } }
解决方案
一、解决415错误(Content-Type不支持)
原因:jQuery的$.post默认会将数据以application/x-www-form-urlencoded格式发送,但后端用@RequestBody接收的是JSON格式数据,导致无法解析。
修改前端代码:改用$.ajax明确设置请求头为application/json,并将对象转为JSON字符串:
function addUserToDB() { let user = { "telephone": "+375296534488", "name": "Potemin", "password": ["p", "a", "s"], "passwordRetry": ["p", "a", "s"], "address": { "city": "New York", "street": "State", "houseNumber": 22 } }; $.ajax({ url: 'http://localhost:8080/registration', type: 'POST', contentType: 'application/json', // 指定请求内容类型为JSON data: JSON.stringify(user), // 将JS对象转为JSON字符串 success: data => console.log(data), error: err => console.error(err) }); }
二、解决403错误(Spring Security拦截)
配置问题分析:
requestMatchers中的URL写错(少了h),且不应匹配完整URL,需直接放行目标接口路径;- 同时配置WebMvc和Spring Security的CORS,易导致冲突;
- 默认CSRF保护会拦截跨域POST请求,开发阶段可临时禁用。
修改Spring Security配置:
package com.project.sushipizzabar.config; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.security.config.Customizer; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.web.SecurityFilterChain; import org.springframework.web.cors.CorsConfiguration; import org.springframework.web.cors.CorsConfigurationSource; import org.springframework.web.cors.UrlBasedCorsConfigurationSource; import java.util.List; @Configuration @EnableWebSecurity public class WebSecurityConfig { @Bean public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { http .csrf(csrf -> csrf.disable()) // 开发阶段临时禁用CSRF,生产环境需配置令牌 .cors(Customizer.withDefaults()) .authorizeHttpRequests(authz -> authz .requestMatchers("/registration").permitAll() // 放行注册接口 .anyRequest().authenticated() // 其他接口需认证 ); return http.build(); } @Bean CorsConfigurationSource corsConfigurationSource() { CorsConfiguration configuration = new CorsConfiguration(); configuration.setAllowedOrigins(List.of("http://localhost:63342")); // 移除末尾斜杠,避免匹配问题 configuration.setAllowedMethods(List.of("GET", "POST", "PUT", "DELETE")); configuration.setAllowedHeaders(List.of("*")); configuration.setAllowCredentials(true); UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); source.registerCorsConfiguration("/**", configuration); return source; } }
关键改动:
- 移除WebMvcConfigurer的CORS配置,统一使用Spring Security的CORS设置;
- 修正
requestMatchers路径,直接放行/registration; - 禁用CSRF(开发环境),解决跨域POST拦截问题;
- 调整
allowedOrigins去掉末尾斜杠,避免匹配异常。
内容的提问来源于stack exchange,提问作者Gvinder
相关产品推荐
相关产品推荐

