$http service cache when the method is post
Asked Answered
R

3

8

when I set the $http to cache requests, I still see duplicate requests (with the same url and same data) sent to the server from browser network,

$http.post(url, data, {cache:true} ).success(function(response) {

I have following questions:

  • Is this a right behaviour?
  • Can we cache post requests?
  • Is this the right way to do so or should I be doing it manually with the $cachefactory ?
Rubie answered 13/10, 2016 at 10:45 Comment(0)
L
9

From the docs:

Only GET and JSONP requests are cached.

If you want to cache POST-requests you would have to do it manually. You will need to make a service/factory that caches responses and serves as a layer before $http. You can use $cacheFactory or just a plain object.

function cacheService($http, $q){      
  var cache = {};      
  this.callSomething = function(postData){
    let deferred = $q.defer();
    let hash = angular.toJson(postData);
    if(cache[hash]){
      deferred.resolve(cache[hash]);
    } else {
      $http.post('path/to/resource', postData).then(function(response){
        cache[hash] = response;
        deferred.resolve(response);
      });
    }        
    return deferred.promise;
  }
}

This is a simple example, you could of course use the same principle and make a more generalized service that takes an URL, postData and a cache object and returns a function that does the request and caches it.

Leenaleeper answered 13/10, 2016 at 11:8 Comment(1)
well explained, Thanks DanielRubie
T
1

I am not sure about cache working. But you can use $cacheFactory for same.

app.factory('Cache', function ($cacheFactory) {
    return $cacheFactory('Cache');
});

app.controller('MyController', function ($scope, $http, Cache) {
    $http.post(url, data, {cache:Cache} ).success(function(response) {}
});

EDIT:

Only GET and JSONP requests are cached.

The cache key is the request URL including search parameters; headers are not considered.

Cached responses are returned asynchronously, in the same way as responses from the server.

If multiple identical requests are made using the same cache, which is not yet populated, one request will be made to the server and remaining requests will return the same response.

A cache-control header on the response does not affect if or how responses are cached.

Threaten answered 13/10, 2016 at 10:57 Comment(1)
@PankajParkar yes. But this will work not work for POST call. Just found a note on this.Threaten
P
0

AngularJS documentation mentions that:

Only GET and JSONP requests are cached.

$http.get(url, {cache: true}) caches the HTTP response in the default cache object (created with $cacheFactory).

Items on the $cachefactory are stored as key-value pairs. The url specified on the $http object is used as the key for the cached value (to be returned). This is one of the reasons it works well with GET which only depends on the URL being hit.

In case of a POST request, the data being sent will also affect the response besides the URL being hit which makes caching a POST request much more complex (since the request will also have to become a part of the key). From the W3 specs:

The actual function performed by the POST method is determined by the server and is usually dependent on the Request-URI.

The action performed by the POST method might not result in a resource that can be identified by a URI.

Responses to this method are not cacheable, unless the response includes appropriate Cache-Control or Expires header fields.

If your data is simple, this SO link might prove a bit useful.

Preeminence answered 13/10, 2016 at 19:23 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.