Angular HttpClient接收并处理302/307响应码;禁用重定向

Angular HttpClient receive and handle 302/307response code; disable redirect

我的组件有以下服务:

@Injectable({
  providedIn: 'root',
})
export class MyService {
    constructor(private httpClient: HttpClient ) { }
}
someFunction() {
   this.httpClient.post(url, data, options)
}

我也有一个 HttpInterceptor 如下:

@Injectable({
  providedIn: 'root'
})
export class HttpInterceptorService implements HttpInterceptor {
  constructor() {}

  intercept(
    req: HttpRequest<any>,
    next: HttpHandler
  ): Observable<HttpEvent<any>> {
    return next.handle(req).do(
      (event: HttpEvent<any>) => {
        if (event instanceof HttpResponse) {
          console.log('############### event status: ', event.status);
        }
        console.log('########### event is: ', event);
      },
      (err: any) => {
        if (err instanceof HttpErrorResponse) {
          console.log('HTTP error status is: ', err.status);
        } 
        console.log('error is: ', err);
      }
    );
  }
}

现在,我的 post 呼叫可能会收到三种类型的响应代码,200302307。现在,在我得到 200 的情况下,一切正常。但是,当我得到 302307 时,默认的 HttpClient 继续跟随响应中的 Location 而不是给我控制权。重定向 url 是刷新 url 但它需要不同类型的处理(GET 而不是 POST 并添加了一些额外的参数)。

如果出现 400 这样的错误,我会在 Interceptor 捕获块中正确地得到错误。

有没有办法禁用 HTTP 重定向并在我的代码中处理重定向?

摘自Mozilla docs: HTTP response status codes:

HTTP response status codes indicate whether a specific HTTP request has been successfully completed. Responses are grouped in five classes:

Informational responses (100–199),

Successful responses (200–299),

Redirects (300–399),

Client errors (400–499),

and Server errors (500–599).

如您所见,3xx HTTP 状态代码是 NOT 错误但重定向。只有 4xx5xx HTTP 状态代码被视为 错误响应 。这就是为什么当您的 angular 应用收到 4xx 响应时,您的拦截器的 catch 块会正确处理它。


摘自Mozilla docs: Redirections in HTTP:

Principle

In HTTP, a redirection is triggered by the server by sending special responses to a request: redirects. HTTP redirects are responses with a status code of 3xx. A browser, when receiving a redirect response, uses the new URL provided and immediately loads it: most of the time, the redirection is transparent to the user, besides a small performance hit.

不幸的是,当浏览器收到 3xx 响应时,它们会主动并立即请求 Location header 中定义的 URI。因此,您无法拦截响应并对其进行处理。


如果 API 是您自己的,您只需将其更改为 return 不同的 HTTP 状态代码会更容易。你提到了 302 returns a "refresh url"。如果您正在使用 JWT 并且您正在尝试刷新令牌,那么 return a 400: BAD REQUEST401: UNAUTHORIZED 并让您的拦截器的错误块句柄调用刷新 url.

如果 API 是其他人的,那么请考虑更改您的 Angular 应用 design/app 流程以处理重定向响应。