javascript - Interceptor de Angular para excluir URLs específicas
Estoy escribiendo interceptores de manera que no tenga que manejar los encabezados en cada servicio que llama a mi API web. El problema con esto es que el 99% de mis llamadas requieren 1 conjunto específico de encabezados, pero el otro 1% solo requiere 1 de los encabezados y no funcionará si los otros están presentes. Sabiendo esto, mi idea es hacer 2 interceptores: el primero añadirá el 1 encabezado que todos usan y el segundo añadirá el resto de los encabezados, excluyendo en el segundo el 1%.
Lo siguiente es cómo estoy excluyendo el 1%, lo cual funciona, pero quiero ver si hay una mejor manera de hacerlo:
intercept(request: HttpRequest<any>, next:HttpHandler: Observable<HttpEvent<any>> {
let position = request.url.indexOf('api/');
if (position > 0){
let destination: string = request.url.substr(position + 4);
let matchFound: boolean = false;
for (let address of this.addressesToUse){
if (new RegExp(address).test(destination)){
matchFound = true;
break;
}
}
if (!matchFound){
...DO WORK to add the headers
}
}
Respuesta #1
Actualización desde Angular 12, usa "contexto", consulta este SO
Sugiero que, a pesar de revisar la solicitud, puedes usar el encabezado para agregar una propiedad "skip", si el encabezado tiene la propiedad skip, simplemente devuelve los reqs
export class CustomInterceptor implements HttpInterceptor {
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
if (req.headers.get("skip"))
return next.handle(req);
....
}
}
Y haces todas las llamadas que necesitas "omitir" el interceptor como
this.http.get(url, {headers:{skip:"true"}});
Respuesta #2
después de comprobar req.headers.get("skip") como sugirió Eliseo, recomendaría eliminar este encabezado de la solicitud ya que solo está relacionado con Angular y no debería transmitirse a la API (en realidad puede causar problemas)
const skipIntercept = request.headers.has('skip');
if (skipIntercept) {
request = request.clone({
headers: request.headers.delete('skip')
});
}
Respuesta #3
Lo que terminé haciendo fue tener un arreglo de URLs (en formato Regex) que no quería que se usaran en el interceptor de la siguiente manera:
import { Injectable } from '@angular/core';
import { HttpEvent, HttpInterceptor, HttpHandler, HttpRequest } from '@angular/common/http';
import { Observable } from 'rxjs';
@Injectable()
export class AddCustomHeadersInterceptor implements HttpInterceptor {
urlsToNotUse: Array<string>;
constructor(
) {
this.urlsToNotUse= [
'myController1/myAction1/.+',
'myController1/myAction2/.+',
'myController1/myAction3'
];
}
intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
if (this.isValidRequestForInterceptor(request.url)) {
let modifiedRequest = request.clone({
setHeaders: {
//DO WORK HERE
}
});
return next.handle(modifiedRequest);
}
return next.handle(request);
}
private isValidRequestForInterceptor(requestUrl: string): boolean {
let positionIndicator: string = 'api/';
let position = requestUrl.indexOf(positionIndicator);
if (position > 0) {
let destination: string = requestUrl.substr(position + positionIndicator.length);
for (let address of this.urlsToNotUse) {
if (new RegExp(address).test(destination)) {
return false;
}
}
}
return true;
}
}
Respuesta #4
Cuando se crea por defecto, HttpClient usará un interceptor. Si quieres evitar esto, puedes crear otra instancia de HttpClient usando el constructor.
@Injectable()
class Service {
private customHttpClient: HttpClient;
constructor(backend: HttpBackend) {
this.customHttpClient = new HttpClient(backend);
}
}La instancia customHttpClient no utilizará el interceptador.
