You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Angular 5 HttpClient无法捕获过期Token返回的401错误响应

Fixing Uncaught 401 Errors with Angular 5 and Spring OAuth 2 Backend

Hey there! Let's figure out why you're not catching that expired token 401 error in Angular 5. I've run into similar issues before, so here are the most common fixes to get that error logged and handled properly:

1. Check Your HTTP Interceptor (Most Likely Culprit)

If you're using a custom HTTP interceptor to attach the OAuth token to requests, it's easy to accidentally "swallow" the error without re-throwing it. Angular's interceptors sit between your request and the server, so if you handle the error there but don't pass it along, your component's subscribe error callback will never see it.

Here's how to adjust your interceptor to log the error and re-throw it:

import { Injectable } from '@angular/core';
import { HttpInterceptor, HttpRequest, HttpHandler, HttpErrorResponse } from '@angular/common/http';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/operator/catch';

@Injectable()
export class AuthInterceptor implements HttpInterceptor {
  intercept(req: HttpRequest<any>, next: HttpHandler): Observable<any> {
    // Clone the request and add your token header
    const authRequest = req.clone({
      headers: req.headers.set('Authorization', `Bearer ${yourTokenVariable}`)
    });

    // Handle the request and catch errors
    return next.handle(authRequest).catch((error: HttpErrorResponse) => {
      // First, log the error details
      console.error('Interceptor caught 401 error:', error);
      console.error('Error message:', error.error); // This should show your backend's invalid token message

      // Critical: Re-throw the error so your component's subscribe can pick it up
      return Observable.throw(error);
    });
  }
}

Don't forget to register the interceptor in your app module's providers array:

@NgModule({
  providers: [
    { provide: HTTP_INTERCEPTORS, useClass: AuthInterceptor, multi: true }
  ]
})
export class AppModule { }

2. Verify Spring Backend CORS Configuration

If your backend's CORS settings are misconfigured, browsers will block access to the 401 error details, even if the server sends them. Make sure your Spring setup allows:

  • Your Angular app's origin
  • Custom headers like Authorization
  • Exposing error response headers (if needed)

Here's a basic Spring CORS configuration example:

@Configuration
public class CorsConfig implements WebMvcConfigurer {
    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**")
                .allowedOrigins("http://your-angular-app-url:4200") // Replace with your app's URL
                .allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS")
                .allowedHeaders("*")
                .allowCredentials(true)
                .exposedHeaders("Authorization"); // Expose headers your app needs to access
    }
}

If you're using Spring Security, add .cors() to your security chain to enable CORS handling:

@Override
protected void configure(HttpSecurity http) throws Exception {
    http.cors()
        .and()
        // Rest of your security configuration...
}

3. Confirm Error Response Format

Check your browser's Network tab (in DevTools) to see what the backend actually returns when the token is expired. If the response isn't valid JSON, Angular might struggle to parse it into an error object. Make sure your Spring backend sends a properly formatted JSON response with the error details, like:

{
  "error": "invalid_token",
  "error_description": "Token has expired"
}

4. Check for Global Error Handlers

If you have a custom ErrorHandler registered globally, it might be catching the error before your component's subscribe does. Ensure that your global handler re-throws the error (or at least logs it) so it propagates down:

import { ErrorHandler, Injectable } from '@angular/core';

@Injectable()
export class GlobalErrorHandler implements ErrorHandler {
  handleError(error: any): void {
    console.error('Global error caught:', error);
    // Re-throw the error so component-level handlers can pick it up
    throw error;
  }
}

Register it in your app module:

@NgModule({
  providers: [{ provide: ErrorHandler, useClass: GlobalErrorHandler }]
})
export class AppModule { }

Once you fix these issues, your component's subscribe error callback should finally catch the 401 error. From there, you can log the details and implement token refresh or redirect to the login page as needed!

内容的提问来源于stack exchange,提问作者Philipp Fock

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 04:24:58