Spring Boot上传图片时POST请求出现Error 403问题求助
解决Axios请求上传图片报403错误的思路
Postman请求正常但Axios报错403,核心差异在于浏览器环境的安全机制(如CSRF、CORS)和请求头自动处理逻辑,以下是可行的排查和解决方向:
1. 移除手动设置的Content-Type头
当使用FormData发送请求时,Axios会自动生成包含boundary参数的正确multipart/form-data请求头。手动设置该头会丢失关键的boundary,导致后端无法正确解析请求体,可能被安全拦截返回403。
修改前端Axios代码:
try { await axios.post("http://localhost:8080/items/addItem/1", formData, { headers: { Authorization: `Bearer ${token}`, // 移除这一行:'Content-Type': 'multipart/form-data' }, }); } catch (err) { console.log(err); }
2. 处理CSRF令牌验证
Spring Security默认启用CSRF保护,Postman等非浏览器工具不会触发校验,但浏览器环境下必须携带CSRF令牌才能通过权限校验。
解决步骤:
- 后端默认已配置CSRF令牌的Cookie分发,无需额外修改
- 前端从Cookie中获取
XSRF-TOKEN,并在请求头中添加X-XSRF-TOKEN:
// 可使用js-cookie库或原生方法获取Cookie const xsrfToken = document.cookie.split('; ').find(row => row.startsWith('XSRF-TOKEN=')).split('=')[1]; try { await axios.post("http://localhost:8080/items/addItem/1", formData, { headers: { Authorization: `Bearer ${token}`, 'X-XSRF-TOKEN': xsrfToken }, withCredentials: true, // 允许携带Cookie }); } catch (err) { console.log(err); }
若仅为测试需要关闭CSRF,可在Spring Security配置中添加:
@Configuration public class SecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { http.csrf().disable(); // 其他权限配置... } }
3. 验证Authorization令牌的正确性
- 确认Axios中使用的
token与Postman测试用的完全一致,无拼写错误、过期问题,且Bearer后必须保留空格 - 打开浏览器开发者工具的Network面板,检查请求头中的
Authorization是否正确发送
4. 检查CORS配置
若前端与后端运行在不同端口,后端需配置正确的CORS规则,允许携带Authorization头和multipart/form-data类型请求:
@Configuration public class CorsConfig implements WebMvcConfigurer { @Override public void addCorsMappings(CorsRegistry registry) { registry.addMapping("/**") .allowedOrigins("http://localhost:你的前端端口") // 指定前端域名 .allowedMethods("GET", "POST", "PUT", "DELETE") .allowedHeaders("*") .allowCredentials(true); // 允许携带Cookie和Authorization头 } }
5. 优化后端请求解析兼容性
在@RequestPart注解中明确指定contentType,确保后端能正确解析JSON格式的item参数:
public void addItem(@RequestPart(value = "item", contentType = "application/json") Item item, @PathVariable Integer id, @RequestPart("imageFile") MultipartFile[] file) { // 方法逻辑... }
前端也可简化item的FormData添加方式:
// 替代Blob写法,直接指定内容类型 formData.append('item', JSON.stringify(item), { contentType: 'application/json' });
内容的提问来源于stack exchange,提问作者Dinu Ispas
相关产品推荐
相关产品推荐

