axios在后端返回401时,获取不到error.response和返回的状态码问题

本文详细介绍了在使用Axios进行前后端交互时遇到的跨域及认证问题,并提供了具体的解决方案,包括如何配置Spring Security以允许预检请求、解决跨域问题以及正确处理认证错误。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在axios中爬过的坑

项目是后端采用的grails + spring cloud + gorm + es等插件做的, 前端采用的是element + axios + vue等,身份认证采用的是spring cloud oauth2.0 . 开发采用的是gradle搭建,语言使用的是groovy
在搭完框架后,正常流程postman都能跑的通,但是如果使用 axios就会遇到跨域问题
然后就解决吧 首先是preflight被禁的问题:
首先是webSecureAdapter这里

class WebSecure extends WebSecurityConfigurerAdapter{
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests().requestMatchers(new RequestMatcher() {
                @Override
                boolean matches(HttpServletRequest request) {
                    return CorsUtils.isPreFlightRequest(request)
                }
            }).permitAll()
          //.and()其他的内容
    }
}

然后发现问题还是没解决 由于认证中心和资源在同一个项目上,暂时未拆分所以 ResourceServerConfigurerAdapter 这里也需要配置

class ResourceConf extends ResourceServerConfigurerAdapter {
@Override
    public void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
        .requestMatchers(new RequestMatcher() {//preflght permitAll 
                    @Override
                    boolean matches(HttpServletRequest request) {
                        return CorsUtils.isPreFlightRequest(request)
                    }
                }).permitAll()
}

好了 ,到这里数据访问的跨域已经解决完成了
但是身份认证的时候也是要跨域的,而且我们的返回数据有部分内容是在header中的,这个在使用spring的框架时,会将其中的header替换掉,继续修改
找了半天,终于找到一个将spring Boot的Filter的修改

private CorsConfiguration buildConfig() {
        CorsConfiguration corsConfiguration = new CorsConfiguration();
        corsConfiguration.addAllowedOrigin("*"); // 1 设置访问源地址
        corsConfiguration.addAllowedHeader("*"); // 2 设置访问源请求头
        corsConfiguration.addAllowedMethod("GET"); // 3 设置访问源请求方法
        corsConfiguration.addAllowedMethod("POST");
        corsConfiguration.addAllowedMethod("DELETE");
        corsConfiguration.addAllowedMethod("PUT");
        corsConfiguration.addAllowedMethod("PATCH");
        corsConfiguration.addExposedHeader("Content-Range")//这里是需要额外配置的header内容
        return corsConfiguration;
    }
    @Bean
    public CorsFilter corsFilter() {
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration("/**", buildConfig()); // 4 对接口配置跨域设置
        return new CorsFilter(source);
    }

好了,到这里好像已经全部配置完成了,数据能正常的访问,接口也都能正常的请求了,….
但是,在使用axios的时候,如果我们使用的token过期,或者token出错的时候,在浏览器能获取401 ,但是axios死活获取不到正常的返回码,找了一堆的源码,可以确定在axios中处理返回结果的位置
在axios 的lib/adapter/xhr.js中

request[loadEvent] = function handleLoad() {
      if (!request || (request.readyState !== 4 && !xDomain)) {
        return;
      }

      // The request errored out and we didn't get a response, this will be
      // handled by onerror instead
      // With one exception: request that using file: protocol, most browsers
      // will return status as 0 even though it's a successful request
      if (request.status === 0 && !(request.responseURL && request.responseURL.indexOf('file:') === 0)) {
        return;//注意这里,这里如果遇到上述的401/403等问题,直接返回,导致我们的axios不能取到返回码
      }

      // Prepare the response
      var responseHeaders = 'getAllResponseHeaders' in request ? parseHeaders(request.getAllResponseHeaders()) : null;
      var responseData = !config.responseType || config.responseType === 'text' ? request.responseText : request.response;
      var response = {
        data: responseData,
        // IE sends 1223 instead of 204 (https://github.com/mzabriskie/axios/issues/201)
        status: request.status === 1223 ? 204 : request.status,
        statusText: request.status === 1223 ? 'No Content' : request.statusText,
        headers: responseHeaders,
        config: config,
        request: request
      };

      settle(resolve, reject, response);

      // Clean up request
      request = null;
    };

同时前端会报错 ,出现跨域问题, 再次整理后端代码,终于发现了WebSecurityConfigurerAdapter中

    @Override
    protected void configure(HttpSecurity http) throws Exception {
    ...
        .csrf().disable();//这里同上面是相同的位置
    }

这里的csrf被禁用后,如果使用跨域,就导致axios不能获取正常error.response
将这里修改为

http.authorizeRequests()
...
.and().cors()

好了 这时候,如果token超时或者使用不正确的token的时候 就能正常的返回error.response了

当你使用ECharts Upload (el-upload) 进行文件上传,并且遇到后台返回500状态(通常是服务器内部错误),但前的`.onerror`回调函数没有被执行的情况,这可能有以下几个原因: 1. **事件监听顺序**:默认情况下,ECharts Upload 的 `error` 事件会先于 `http-request-error` 或 `response-error` 事件触发。如果服务器返回的状态不是特定的错误范围(如4XX或5XX),`error` 可能不会被捕获。你需要确认是否在 `http-request-error` 或 `response-error` 中处理这类情况。 2. **错误处理配置**:检查你的 `el-upload` 组件是否有针对不同错误类型的自定义处理策略,比如设置了某个状态不触发 `error`,而是在其他回调中处理。 3. **开发者工具设置**:检查浏览器开发者工具网络面板,看看响应内容有没有包含错误信息,有候服务器直接返回500可能导致前无法获取到足够的错误数据。 4. **回调函数的问题**:确认 `onerror` 回调是否正确配置并绑定到了 `el-upload` 上。可能是函数引用失效或者语法错误导致未生效。 如果你想要确保在遇到服务器内部错误始终触发错误处理,你可以尝试手动添加一个 `http-request-error` 或 `response-error` 的处理器,或者将所有非成功状态都视为错误: ```javascript <template> <el-upload :http-request="customRequest" :on-error="handleError" ...other-configs ></el-upload> </template> <script> export default { methods: { customRequest(file, options) { return axios(options) .then(response => response.data) .catch(error => { if (error.response && error.response.status >= 500) { this.handleError(error); } // 更具体的错误处理... }); }, handleError(error) { console.error('Upload failed:', error); // 在这里添加你的错误处理代 }, }, }; </script> ```
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值