AngularJS: Как я могу кэшировать данные json, возвращенные из вызова $http?

Как я могу кэшировать данные json, возвращаемые из вызова $http. Я использую следующий стиль вызова $http:

$http({
        url: 'SomeWebMethodUrl',
        method: "POST",
        data: "{'query':'somevalue'}",
        headers: { 'Content-Type': 'application/json' }
    }).success(function (data, status, headers, config) {
        //something in success
    }).error(function (data, status, headers, config) {
        //something in error
    });

Я посмотрел следующий учебник: https://coderwall.com/p/40axlq на ответ кэширования сервера от вызова $http. Но он объясняет стиль $http.get() и кэширует данные и не будет делать второй запрос $http, если абсолютный URL-адрес тот же.

Можно ли использовать кеширование с моим стилем вызова $http, когда свойство "data" одинаково для одних и тех же вызовов веб-метода в будущем? Я использую веб-сервис ASP.net ASMX для своих WebMethods.

Ответы

Ответ 1

Кэш angular.js предназначен только для вызовов HTTP GET. Это согласуется с намерением HTTP-протокола, поскольку HTTP-серверы обычно не смотрят за пределы URL-адреса, HTTP-метода и заголовков Cache-Control, чтобы определить, могут ли они отвечать на запрос с кешированным контентом. Соответственно, авторы angular не распространяли функции кэширования на другие методы HTTP.

Другой способ взглянуть на это состоит в том, что служба angular $cache - это просто простое хранилище ключей, с URL-адресом запроса, действующим в качестве ключа, и ответом на запрос HTTP GET значение, которое хранится локально, а не на сервере.

Когда вы думаете об этом, становится понятным, почему более сложно кэшировать ответ на запрос POST. Содержимое, возвращаемое запросом POST, зависит не только от URL-адреса, но и от содержимого POST. Чтобы кэшировать результат в хранилище ключей, вам нужен механизм для создания уникального ключа, который идентифицирует как URL, так и передаваемые данные.

Если вы достаточно просты, мое предложение состоит в том, чтобы написать свой собственный кеш, который проверяется перед использованием службы angular $http. Не зная больше о методе данных, я не могу дать вам полный пример, но вы можете сделать что-то вроде этого:

angular.module('myModule').service('myDataService', function($cacheFactory, $http) {

  var cache = $cacheFactory('dataCache');

  function success(data, status, headers, config) {
    // some success thing
  }

  function error(data, stats, headers, config) {
    // some error thing
  }

  this.getSomeData = function(url, query) {
    var cacheId = url + '*' + query;
    var cachedData = cache.get(cacheId);
    // Return the data if we already have it
    if (cachedData) {
      success(cachedData);
      return;
    }

    // Got get it since it not in the cache
    $http({url: url,
           method: 'POST',
           data: {query: query},
           headers: { 'Content-Type': 'application/json' }  // Probably not necessary, $http I think does this 
         }).success(function(data, status, headers, config) {
              // Put this in our cache using our 'unique' id for future use
              cache.put(cacheId, data);
              success(data, status, headers, configs);
         }).error(error);    

  };

});

Затем вы замените эту службу обертки, в которой вы в настоящее время используете службу raw $http.

Суть заключается в том, чтобы реализовать свой собственный кеш, который понимает "url + data" в качестве ключа, прежде чем фактически называть службу $http.

Ответ 2

Использование запроса POST, используемого для добавления новых записей в хранилище данных, PUT и DELETE изменяет состояние хранилища данных. И нет смысла наличать никому из них.

Только GET извлекает данные без изменения хранилища данных. И это имеет смысл наделить его ответом.