Axios: Unterstützung für das Caching von GET-Anfragen hinzufügen

Erstellt am 11. Dez. 2014  ·  18Kommentare  ·  Quelle: axios/axios

Hilfreichster Kommentar

Ich habe eine Reihe von Erweiterungen für Axios erstellt, einschließlich des Caching von GET-Anfragen, die vom benutzerdefinierten Adaptermechanismus von Axios und dem lru-Cache abhängig sind, und das Wichtigste ist, dass die Testabdeckung 100% erreicht hat 🎉. https://github.com/kuitos/axios-extensions

Beispiel

import axios from 'axios';
import { cacheAdapterEnhancer } from 'axios-extensions';

const http = axios.create({
    baseURL: '/',
    headers: { 'Cache-Control': 'no-cache' },
    // cache will be enabled by default
    adapter: cacheAdapterEnhancer(axios.defaults.adapter)
});

http.get('/users'); // make real http request
http.get('/users'); // use the response from the cache of previous request, without real http request made
http.get('/users', { cache: false }); // disable cache manually and the the real http request invoked

btw, ich habe noch eine mächtige Erweiterung gemacht, die die Anfragen in der Schwellenzeit drosseln kann.

import axios from 'axios';
import { throttleAdapterEnhancer } from 'axios-extensions';

const http = axios.create({
    baseURL: '/',
    headers: { 'Cache-Control': 'no-cache' },
    adapter: throttleAdapterEnhancer(axios.defaults.adapter, 2 * 1000)
});

http.get('/users'); // make real http request
http.get('/users'); // responsed from the cache
http.get('/users'); // responsed from the cache

Für weitere Informationen können Sie das API-Dokument überprüfen

Ich hoffe, das kann für Sie nützlich sein und zögern Sie nicht, Fragen zu stellen🙂

Alle 18 Kommentare

Heh, das habe ich mir gerade angeschaut! Ich dachte, dass ein Abfangjäger oder ein Transformator verwendet werden könnte, der sich sofort mit einer Antwort löst, aber noch kein Glück.

Felix sieht auf jeden Fall interessant aus...

:+1: Die Node-Version ist für mich nicht sehr nützlich, bis wir eine steckbare Caching-Schicht haben.

Irgendwelche Fortschritte im Browser? Funktioniert der Cache?

Bump... brauche das oder ich tausche Axios gegen Superagent aus oder frage nach unserer Produktions-App... verursacht enorme Verlangsamungen

@mzabriskie Ich habe Unterstützung für ttls in mzabriskie/felix#4 hinzugefügt und kann dies angehen, wenn Ihnen meine Implementierung dort gefällt.

Ich bin froh zu sehen, dass dieses Problem wiederbelebt wird, es würde mich davor bewahren, ein paar Boilerplates schreiben zu müssen :smile:

Ich denke, dass Caching derzeit über Interceptors implementiert werden kann, obwohl es nicht sehr sauber ist:

cache(axios, options);

function cache(instance, options) {
  instance.interceptors.request.use(function(config) {
    if (!config.method === 'get') {
      return config;
    }
    return cache.get(generateOptions(config, options))
      .then(createCachedError, function() { return config; });
  });
  instance.interceptors.response.use(null, function(error) {
    if (error.cachedResult) {
      return Promise.resolve(error.cachedResult);
    }
    return Promise.reject(error);
  });
}

Ein saubererer Weg, dies zu tun, könnte darin bestehen, den Standardadapter (http, xhr) in den Instanzstandardeinstellungen zu definieren und dann einen benutzerdefinierten Adapter wie diesen zu verwenden:

axios.get('url', { adapter: cachingAdapter });

function cachingAdapter(resolve, reject, config) {
  cache.get(generateOptions(config, options)).then(function(result) {
    resolve(createResponse(result));
  }, function() {
    axios.defaults.adapter(resolve, reject, config);
  });
}

Ich denke auch, dass Adapter Versprechen zurückgeben sollten, anstatt die Lösungs- und Ablehnungsmethoden zu erhalten, aber das ist derzeit kein Problem.

Ich denke, Axios sollte das Caching aus dem Kern herauslassen und eine solche Implementierung zulassen.

Was denken Sie?

Ich schließe dieses Problem aufgrund von Inaktivität. Fühlen Sie sich frei, es wieder zu öffnen, wenn Sie der Meinung sind, dass es einer weiteren Diskussion bedarf ;)

Gibt es dafür eine Lösung? Es scheint seltsam, dass es keine offensichtliche Möglichkeit gibt, Anfragen zwischenzuspeichern...

@rubennorte was sind Optionen im Cache (axios, Optionen); ?

@john1jan hypothetische Optionen für den von Ihnen verwendeten Cache-Client. Zum Beispiel Optionen für einen Catbox- Client.

Abhängig von Ihrem Anwendungsfall können Sie die Funktion get einfach überschreiben:

// Create intercepting get function which returns cached promise,
// hence multiple requests to the same URL will be resolved by
// a single promise.
function cachingGet (get) {
  const cache = new Map()

  return function cachedGet (url) {
    const key = url

    if (cache.has(key)) {
      return cache.get(key)
    } else {
      const request = get(...arguments)
      cache.set(key, request)
      return request
    }
  }
}

const instance = axios.create(config)
instance.get = cachingGet(instance.get)

Vielleicht wäre eine bessere Lösung die Verwendung eines Adaptermusters?

Habe etwas dafür gemacht https://github.com/RasCarlito/axios-cache-adapter :)
Ich habe eine erste Version veröffentlicht, aber es bedarf weiterer Tests. Hoffe, es kann für andere nützlich sein.
Ich werde es in einem großen Projekt für einen meiner Kunden implementieren.

Standardmäßig verwendet es einen benutzerdefinierten Speicher im Arbeitsspeicher für den Cache.
In Browsern kann es eine versprochene localStorage Instanz wie localForage empfangen.
Ich habe nicht nach einer gleichwertigen Lösung in Node gesucht.

Beispiel:

import axios from 'axios'
import { setupCache } from 'axios-cache-adapter'

const cache = setupCache(/* options */)
const api = axios.create({
  adapter: cache.adapter
})

api.get('some-url').then(response => /* Do something awesome with response.data \o/ */)

Prost :bier:

Ich habe eine Reihe von Erweiterungen für Axios erstellt, einschließlich des Caching von GET-Anfragen, die vom benutzerdefinierten Adaptermechanismus von Axios und dem lru-Cache abhängig sind, und das Wichtigste ist, dass die Testabdeckung 100% erreicht hat 🎉. https://github.com/kuitos/axios-extensions

Beispiel

import axios from 'axios';
import { cacheAdapterEnhancer } from 'axios-extensions';

const http = axios.create({
    baseURL: '/',
    headers: { 'Cache-Control': 'no-cache' },
    // cache will be enabled by default
    adapter: cacheAdapterEnhancer(axios.defaults.adapter)
});

http.get('/users'); // make real http request
http.get('/users'); // use the response from the cache of previous request, without real http request made
http.get('/users', { cache: false }); // disable cache manually and the the real http request invoked

btw, ich habe noch eine mächtige Erweiterung gemacht, die die Anfragen in der Schwellenzeit drosseln kann.

import axios from 'axios';
import { throttleAdapterEnhancer } from 'axios-extensions';

const http = axios.create({
    baseURL: '/',
    headers: { 'Cache-Control': 'no-cache' },
    adapter: throttleAdapterEnhancer(axios.defaults.adapter, 2 * 1000)
});

http.get('/users'); // make real http request
http.get('/users'); // responsed from the cache
http.get('/users'); // responsed from the cache

Für weitere Informationen können Sie das API-Dokument überprüfen

Ich hoffe, das kann für Sie nützlich sein und zögern Sie nicht, Fragen zu stellen🙂

Für Leute, die nur den Cache deaktivieren möchten, den ich verwendet habe:
const config = { headers: {'Content-Type': 'application/json','Cache-Control' : 'no-cache'}};
und rufe meine API so auf:
const { data } = await axios.get('http://www.youraddress.com/api/data.json', config);

Wie wäre es damit in TypeScript [kann leicht eine JS-Sache sein] -

export class AxiosFactory {

    private static CACHE_MAP = new Map<string, AxiosResponse>();

    private static attachTokenToURL(config): AxiosFactory {
        let urlToUse = config.url;
        // Custom Token Attachment
        return config;
    }

    private static cachingAdapter(config: AxiosRequestConfig): AxiosPromise<AxiosResponse<any>> {
        if (!!AxiosFactory.CACHE_MAP.get(config.url)) {
            return new Promise((resolve, reject) => {
                resolve(AxiosFactory.CACHE_MAP.get(config.url));
            });
        } else {
            return axios.defaults.adapter(config);
        }
    }

    static GetAxiosConfig(baseUrl, enableCaching = false) {
        let defaultConfig = {
            baseURL: baseUrl,
            headers: { "Authorization": TokenService.GetTokenValue() } //optional
        } as AxiosRequestConfig;

        if (enableCaching) {
            defaultConfig.adapter = AxiosFactory.cachingAdapter
        }
        const instance = axios.create(defaultConfig);

        // Only for Adding Tokens in here.
        instance.interceptors.request.use((config) => {
            config = AxiosFactory.attachTokenToURL(config);
            return config;
        }, (error) => {
            return Promise.reject(error);
        });

        // Only for catching Caches
        instance.interceptors.response.use((response) => {
            AxiosFactory.CACHE_MAP.set(response.request.responseURL, response);
            return response;
        }, (error) => {
            return Promise.reject(error);
        });

        return instance;
    }
}

const config = { headers: {'Content-Type': 'application/json','Cache-Control' : 'no-cache'}};

Anforderungs-URL: http://myurl
Referrer-Richtlinie: No-Referrer-When-Downgrade
Vorläufige Überschriften werden angezeigt
Akzeptieren: application/json, text/plain, /
ApiKey: myapikey
Cache-Kontrolle: kein Cache
Referer: http://localhost :3000/orders
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, wie Gecko) Chrome/81.0.4044.113 Safari/537.36

es verursacht ein Problem bei der Anfrage mit 'Cache-Control': 'no-cache' in header .
Wie kann ich die Cache-Steuerung in meiner Axios-Instanz implementieren?

Mein Code:

const Instanz = axios.create({baseURL: url});

instance.defaults.headers['ApiKey'] = Schlüssel;
instance.defaults.headers['Cache-Control'] = "kein Cache";

Ich habe auch Ihre Lösung ausprobiert, indem ich config in einer einzigen Anfrage übergeben habe. aber kein glück.

was wird die lösung sein?

War diese Seite hilfreich?
0 / 5 - 0 Bewertungen