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 呼叫可能会收到三种类型的响应代码,200
或 302
或 307
。现在,在我得到 200
的情况下,一切正常。但是,当我得到 302
或 307
时,默认的 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 错误但重定向。只有 4xx
和 5xx
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 REQUEST
或 401: UNAUTHORIZED
并让您的拦截器的错误块句柄调用刷新 url.
如果 API 是其他人的,那么请考虑更改您的 Angular 应用 design/app 流程以处理重定向响应。
我的组件有以下服务:
@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 呼叫可能会收到三种类型的响应代码,200
或 302
或 307
。现在,在我得到 200
的情况下,一切正常。但是,当我得到 302
或 307
时,默认的 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 错误但重定向。只有 4xx
和 5xx
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 REQUEST
或 401: UNAUTHORIZED
并让您的拦截器的错误块句柄调用刷新 url.
如果 API 是其他人的,那么请考虑更改您的 Angular 应用 design/app 流程以处理重定向响应。