Wie können Sie Axios Interceptors verwenden?

77

Ich habe Axios-Dokumentation gesehen, aber alles, was darin steht, ist

// Add a request interceptor
axios.interceptors.request.use(function (config) {
    // Do something before request is sent
    return config;
  }, function (error) {
    // Do something with request error
    return Promise.reject(error);
  });

// Add a response interceptor
axios.interceptors.response.use(function (response) {
  // Do something with response data
  return response;
}, function (error) {
  // Do something with response error
  return Promise.reject(error);
});

Auch viele Tutorials zeigen nur diesen Code, aber ich bin verwirrt, wofür er verwendet wird. Kann mir bitte jemand ein einfaches Beispiel geben, dem ich folgen kann?

Akash Salunkhe
quelle

Antworten:

112

Einfach ausgedrückt ist es eher ein Kontrollpunkt für jede http-Aktion. Jeder getätigte API-Aufruf wird durch diesen Interceptor geleitet.

Warum also zwei Abfangjäger?

Ein API-Aufruf besteht aus zwei Hälften, einer Anfrage und einer Antwort. Da es sich wie ein Prüfpunkt verhält, haben die Anforderung und die Antwort separate Abfangjäger.

Einige Anforderungs-Interceptor-Anwendungsfälle -

Angenommen, Sie möchten vor einer Anfrage prüfen, ob Ihre Anmeldeinformationen gültig sind. Anstatt einen API-Aufruf zu tätigen, können Sie ihn auf Interceptor-Ebene überprüfen, um festzustellen, ob Ihre Anmeldeinformationen gültig sind.

Angenommen, Sie müssen jeder gestellten Anforderung ein Token hinzufügen, anstatt die Token-Additionslogik bei jedem Axios-Aufruf zu duplizieren, können Sie einen Interceptor erstellen, der bei jeder gestellten Anforderung ein Token anfügt.

Einige Anwendungsfälle für Antwort-Interceptors -

Angenommen, Sie haben eine Antwort erhalten, und anhand der API-Antworten, die Sie ableiten möchten, können Sie ableiten, dass der Benutzer angemeldet ist. Im Antwort-Interceptor können Sie also eine Klasse initialisieren, die den angemeldeten Status des Benutzers verarbeitet, und diese für das von Ihnen verwendete Antwortobjekt entsprechend aktualisieren empfangen.

Angenommen, Sie haben eine API mit gültigen API-Anmeldeinformationen angefordert, haben jedoch nicht die gültige Rolle für den Zugriff auf die Daten. Sie können also eine Warnung vom Antwortabfangjäger auslösen, die besagt, dass der Benutzer nicht zulässig ist. Auf diese Weise werden Sie vor der nicht autorisierten API-Fehlerbehandlung bewahrt, die Sie für jede von Ihnen gestellte Axios-Anforderung ausführen müssten.

Könnte jetzt mit diesen Anwendungsfällen kommen.

Hoffe das hilft :)

BEARBEITEN

Da diese Antwort an Bedeutung gewinnt, finden Sie hier einige Codebeispiele

Der Anforderungsabfangjäger

=> Sie können das Konfigurationsobjekt von axios (falls erforderlich) drucken, indem Sie Folgendes tun (in diesem Fall durch Überprüfen der Umgebungsvariablen):

const DEBUG = process.env.NODE_ENV === "development";

axios.interceptors.request.use((config) => {
    /** In dev, intercepts request and logs it into console for dev */
    if (DEBUG) { console.info("✉️ ", config); }
    return config;
}, (error) => {
    if (DEBUG) { console.error("✉️ ", error); }
    return Promise.reject(error);
});

=> Wenn man überprüfen möchte, welche Header übergeben werden / weitere generische Header hinzufügen möchte, ist diese im config.headersObjekt verfügbar . Zum Beispiel:

axios.interceptors.request.use((config) => {
    config.headers.genericKey = "someGenericValue";
    return config;
}, (error) => {
    return Promise.reject(error);
});

=> Falls es sich um eine GETAnfrage handelt, finden Sie die gesendeten Abfrageparameter im config.paramsObjekt.

Der Antwortabfangjäger

=> Optional können Sie sogar die API-Antwort auf Interceptor-Ebene analysieren und die analysierte Antwort anstelle der ursprünglichen Antwort weitergeben. Dies kann Ihnen die Zeit sparen, die Parsing-Logik immer wieder zu schreiben, wenn die API an mehreren Stellen auf dieselbe Weise verwendet wird. Eine Möglichkeit, dies zu tun, besteht darin, einen zusätzlichen Parameter im api-requestund den gleichen Parameter im Antwort-Interceptor zu übergeben, um Ihre Aktion auszuführen. Zum Beispiel:

//Assume we pass an extra parameter "parse: true" 
axios.get("/city-list", { parse: true });

Einmal können wir im Antwort-Interceptor Folgendes verwenden:

axios.interceptors.response.use((response) => {
    if (response.config.parse) {
        //perform the manipulation here and change the response object
    }
    return response;
}, (error) => {
    return Promise.reject(error.message);
});

In diesem Fall wird die Manipulation immer dann ausgeführt, wenn sich ein parseObjekt darin response.configbefindet. In den übrigen Fällen funktioniert sie unverändert.

=> Sie können sogar die ankommenden HTTPCodes anzeigen und dann die Entscheidung treffen. Zum Beispiel:

axios.interceptors.response.use((response) => {
    if(response.status === 401) {
         alert("You are not authorized");
    }
    return response;
}, (error) => {
    if (error.response && error.response.data) {
        return Promise.reject(error.response.data);
    }
    return Promise.reject(error.message);
});
Aseem Upadhyay
quelle
1
Wo schreiben Sie diese Interceptors - auf jeder Komponente oder an einem globalen / zentralen Ort für die gesamte App?
James Poulose
@ JamesPoulose sollte sich an einem zentralen Ort befinden, da sein Verhalten ziemlich einfach ist. Es kann auch auf Komponentenebene geschrieben werden, dies führt jedoch im Allgemeinen zu einer Codeduplizierung. was nicht weise wäre
Aseem Upadhyay
1
@JamesPoulose Sie können Ihre Service-Schicht trennen und den Interceptor an der Basis dieser Service-Schicht haben, so etwas wie services/index.js. So bleibt die Frontend-App an einem Ort und die Dienste bleiben getrennt und plattformunabhängig: D
Aseem Upadhyay
1
@AseemUpadhyay Ich legte diesen Code in services/index.jsund export default axiosund dann , import axios from "services/index.js"wo ich axios verwenden. Aber ich sehe, dass andere im Internet stattdessen einen Wrapper für Axios erstellen. Welchen Ansatz verwenden Sie persönlich? Danke
Raj
1
@JamesPoulose Ich habe dieses Problem gelöst, indem ich einen Ordner "services" unter dem Ordner "src" erstellt habe. In diesem Verzeichnis erstelle ich eine "request.js" oder einen beliebigen benutzerdefinierten Namen zum Schreiben des Interceptors.
Novonimo
17

Es ist wie eine Middleware, im Grunde wird es bei jeder Anfrage (sei es GET, POST, PUT, DELETE) oder bei jeder Antwort (die Antwort, die Sie vom Server erhalten) hinzugefügt. Es wird häufig in Fällen verwendet, in denen eine Autorisierung erforderlich ist.

Schauen Sie sich das an: Axios Interceptors und asynchrones Login

Hier ist ein weiterer Artikel dazu mit einem anderen Beispiel: https://medium.com/@danielalvidrez/handling-error-responses-with-grace-b6fd3c5886f0

Das Wesentliche eines der Beispiele ist also, dass Sie Interceptor verwenden können, um festzustellen, ob Ihr Autorisierungstoken abgelaufen ist (wenn Sie beispielsweise 403 erhalten), und um die Seite umzuleiten.

Constantin Chirila
quelle
6

Sie können diesen Code beispielsweise verwenden, wenn Sie die Zeit ab dem Zeitpunkt des Versands der Anforderung bis zum Erhalt der Antwort erfassen möchten:

const axios = require("axios");

(async () => {
  axios.interceptors.request.use(
    function (req) {
      req.time = { startTime: new Date() };
      return req;
    },
    (err) => {
      return Promise.reject(err);
    }
  );

  axios.interceptors.response.use(
    function (res) {
      res.config.time.endTime = new Date();
      res.duration =
        res.config.time.endTime - res.config.time.startTime;
      return res;
    },
    (err) => {
      return Promise.reject(err);
    }
  );

  axios
    .get("http://localhost:3000")
    .then((res) => {
      console.log(res.duration)
    })
    .catch((err) => {
      console.log(err);
    });
})();
Steve.g
quelle
1
Ich habe Ihre Antwort positiv bewertet, weil Sie sowohl die Abfangjäger als auch den tatsächlichen Anruf an einem Ort gezeigt haben. Es fiel mir schwer, die beiden zusammenzufügen.
Woodsman