angular 缓存post请求的方法

angular 缓存post请求的方法

http://blog.csdn.net/qq_24472595/article/details/70160881

原创 2017年04月13日 18:41:12

问题

  • 默认情况下,angular的$http仅仅缓存“get”和’jsonp’的请求数据.

angular $http缓存的源码分析

// line 11737

      if ((config.cache || defaults.cache) && config.cache !== false &&
          (config.method === 'GET' || config.method === 'JSONP')) {//判断是否要缓存
        cache = isObject(config.cache) ? config.cache
              : isObject(defaults.cache) ? defaults.cache
              : defaultCache;
          console.log('cache',cache);//选择缓存对象
      }
         if (cache) {
            cachedResp = cache.get(url);//获取缓存
            ...
        }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 首先我们要通过 config.method和config.cache的校验
  • 其次要一个唯一的url,可以利用angular自带的URL编码服务$httpParamSerializer,编码data对象来生成,其他的方法也可以,只要唯一就行
  • 另外,如果只是单纯的改成get请求,发给后端的时候,就真是是get请求了。而我们发给后台的应该是post请求。所以第一次请求,必须原封不动的发给后台。这就导致了,我们只能自己创建一个容器来缓存数据。并且是cacheFactoryhttp才能识别。

方法

  • 将post请求伪装成get请求,让$http可识别
  • 缓存POST数据并不难,主要是要让httppostsuccesserror.http的缓存校验,让$http的代码能够执行下去.
   $http.post(url,data).then(success,error);
  • 1
  • 思路

    1. 新建一个拦截器

       var myapp=angular.module('myapp',[]);
      myapp.config(function ($httpProvider) {
        $httpProvider.interceptors.push(function ($q) {
            return {
                request:function (config) {            
                    return config
                },
                response:function (response) {
                    return response;
                }
            }
        })
      });
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
    2. 创建一个缓存post数据的容器

       var cache=angular.injector(['ng']).get('$injector').get('$cacheFactory')('$httpPost');
      • 1
    3. 在request请求时,判断是否为POST请求,并且设置了cache:true,如果是,并且cache过数据,则伪装为’GET’方法,如果没有cache过则直接pass.

       request:function (config) {
                    if(config.cache&&config.method==='POST'){
                        //开始计数
                        var url=config.url+'?'+config.paramSerializer(config.data);
                        console.log('url',url,cache.get(url));
                        if(cache.get(url)){
                            config.cache=cache;
                            config.method='GET';
                            config.url=url;
                        }
                    }
                    return config
                },
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
    4. 在response返回时,判断是否为POST请求,并且设置了cache:true,如果是则cache它

      response:function (response) {
                    var config=response.config;
                    if(response.config.cache&&response.config.method==='POST'){
                        var url=config.url+'?'+config.paramSerializer(config.data);
                        cache.put(url,response.data);
                        console.log('save Cache',url,cache.get(url));
                    }
                    return response;
                }
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9

代码

  • 完整demo(angular version 1.5.8)
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<script src="./angular.js"></script>
<div ng-app="myapp">
    <div ng-controller="myctrl">
        <span ng-bind="name"></span>
        <span ng-bind="age"></span>
        <button ng-click="load()">加载</button>
    </div>
</div>
<script>
  var myapp=angular.module('myapp',[]);
  myapp.config(function ($httpProvider) {
      $httpProvider.interceptors.push(function ($q) {
          var cache=angular.injector(['ng']).get('$injector').get('$cacheFactory')('$httpPost');
          console.info('cache',cache);
          return {
              request:function (config) {
                  if(config.cache&&config.method==='POST'){
                      //开始计数
                      var url=config.url+'?'+config.paramSerializer(config.data);
                      console.log('url',url,cache.get(url));
                      if(cache.get(url)){
                          config.cache=cache;
                          config.method='GET';
                          config.url=url;
                      }
                  }
                  return config
              },
              requestError:function (rejection) {
                  console.log('rejection',rejection);
                  return rejection;
              },
              response:function (response) {
                  var config=response.config;
                  if(response.config.cache&&response.config.method==='POST'){
                      var url=config.url+'?'+config.paramSerializer(config.data);
                      cache.put(url,response.data);
                      console.log('save Cache',url,cache.get(url));
                  }
                  return response;
              }
          }
      })
  });
  myapp.controller('myctrl',function ($scope,$http) {
      $scope.name='demo';
      $scope.age=100;
      $scope.load=function () {
          $http({
              url:'data.json',
              method:'post',
              data:{name:1},
              cache:true}).success(function (data) {
              console.log('ajax result',data);
              $scope.name=data.name;
              $scope.age=data.age;
          }).error(function (error) {
              console.error('error',error);
          });
      };
      $scope.load();
  })
</script>
</body>
</html>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • data.json
{
  "name":"gyanxie",
  "age":"万岁万万岁"
}
  • 1
  • 2
  • 3
  • 4
版权声明:本文为博主原创文章,未经博主允许不得转载。
 
posted @ 2017-12-27 15:13  sky20080101  阅读(312)  评论(0)    收藏  举报