为什么前端传了token,后端一直获取不到?一直报跨域错误?

这是我的前端代码

这是我的后端拦截器

那就需要了解一下 预检请求

对于非简单请求(如PUT、DELETE或包含自定义HTTP头的请求),浏览器会先发送一个OPTIONS请求到目标服务器,询问是否允许该跨域请求。这个过程称为预检请求。

当options请求到达我服务器时,被拦截器拦住了,获取不到跨域的规则。所以浏览器也不会发送实际的请求。那么一共有两种解决办法

1、过滤器
package com.book.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;

@Configuration
public class GlobalCorsConfig {

    @Bean
    public CorsFilter corsFilter() {
        //1. 添加 CORS配置信息
        CorsConfiguration config = new CorsConfiguration();
        // 放行哪些原始域
        config.addAllowedOrigin("http://localhost:8080");
        // 是否发送 Cookie
        config.setAllowCredentials(true);
        // 放行哪些请求方式
        config.addAllowedMethod("*");
        // 放行哪些原始请求头部信息
        config.addAllowedHeader("*");
        // 暴露哪些头部信息
        config.addExposedHeader("*");
        //2. 添加映射路径
        UrlBasedCorsConfigurationSource corsConfigurationSource = new UrlBasedCorsConfigurationSource();
        corsConfigurationSource.registerCorsConfiguration("/**",config);
        //3. 返回新的CorsFilter
        return new CorsFilter(corsConfigurationSource);
    }

}
2、拦截器中放行options请求(preHandle方法中)
//判断是否需要拦截
        //拦截器取到请求先进行判断,如果是OPTIONS请求,则放行
        if("OPTIONS".equals(request.getMethod().toUpperCase())) {
            System.out.println("Method:OPTIONS");
            return true;
        }

### 前端 POST 请求带上请求头 Token 后端接收为空的原因 当前端通过 `POST` 请求向后端递带有请求头的 `token` 参数时,如果后端接收到的数据为空,则可能涉及以下几个方面的原因: #### 1. 预检请求的影响 浏览器在发起 `POST` 或其他非简单请求之前会先发送一个 `OPTIONS` 预检请求。此预检请求用于确认服务器允许的实际请求方法和头部字段[^1]。由于 `OPTIONS` 请求本身不携带任何实际数据或请求头中的自定义字段(如 `Authorization`),因此即使前端设置了请求头,在预检阶段这些设置也不会生效。 #### 2. 请求头未正确配置 如果前端框架(如 Axios)未正确配置请求头,或者后端接口未能识别特定的 HTTP 头部字段(例如 `Authorization` 字段),则可能导致后端无法读取到该字段的内容[^2]。 #### 3. 后端参数绑定问题 后端控制器中使用的注解可能会导致参数解析失败。例如,使用 `@RequestParam` 注解来接收本应位于请求头中的 `token` 数据会导致错误,因为 `@RequestParam` 主要处理 URL 查询字符串或表单提交的数据而非请求头内容[^3]。 --- ### 解决方案 以下是针对上述问题的具体解决办法: #### 方案一:确保 CORS 设置支持所需 Header 对于场景下的预检机制,需调整服务端的策略以显式声明哪些 Headers 是被允许的。比如 Spring Boot 中可以通过如下方式实现: ```java @Configuration public class WebConfig implements WebMvcConfigurer { @Override public void addCorsMappings(CorsRegistry registry) { registry.addMapping("/**") .allowedOrigins("*") // 允许所有源访问 .allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS") // 支持的方法 .allowedHeaders("Content-Type", "Authorization"); // 显式指定 Authorization header } } ``` #### 方案二:验证并修正 Frontend 的 Request Configurations 检查前端代码是否已正确定义了请求头部分。如果是基于 Axios 库开发的应用程序,可以尝试全局默认值设定或单独调用实例的方式添加 headers: ```javascript // 方法 A - 设定全局默认值 axios.defaults.headers.common['Authorization'] = 'Bearer your_token_here'; // 方法 B - 单独创建带配置项的新实例 const instance = axios.create({ baseURL: '/api', timeout: 5000, headers: { 'Authorization': 'Bearer your_token_here' }, }); instance.post('/endpoint', data); ``` 注意此处 `'your_token_here'` 替换为真实的 token 值。 #### 方案三:修改 Backend Controller 来适配 Header Data 假如当前项目架构设计使得某些路径仅依赖于 request body 提供的信息而忽略掉 headers 内容的话,那么就需要重新审视业务逻辑流程,并相应更改 controller 定义形式。例如改用 `HttpServletRequest` 对象直接提取 header 值而不是依靠 spring mvc 自动注入机制完成映射操作: ```java @RestController @RequestMapping("/example") public class ExampleController { @PostMapping(value="/secure-endpoint") public ResponseEntity<String> secureEndpoint(HttpServletRequest httpRequest){ String authHeader=httpRequest.getHeader("Authorization"); if(authHeader!=null && !authHeader.isEmpty()){ return new ResponseEntity<>("Authenticated successfully.", HttpStatus.OK); }else{ return new ResponseEntity<>("Missing or invalid authorization information.",HttpStatus.UNAUTHORIZED); } } } ``` 以上片段展示了如何利用原始 HttpServletRequest 接口手动获取名为 `"Authorization"` 的 header 值[^4]。 #### 方案四:排查复杂嵌套结构引起的序列化异常 有时尽管表面上看似乎已经完成了必要的准备工作,但由于输模型过于繁琐(即存在多级对象封装关系),仍然会出现丢失重要属性的现象。这时应该仔细核验双方约定好的 DTO 类型定义是否存在差异之处;另外还要留意 JSON parser 工具版本兼容性状况以防意外情况发生[^5]。 --- ### 总结 综上所述,从前端后端整个链路都需要逐一排查潜在隐患点才能彻底根除此类 bug 。重点在于合理运用 cors policy ,精确控制 http message format 及其关联 metadata (headers etc.) , 并且保持两端通信协议一致性从而保障信息安全高效流通。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值