angular 缓存post请求的方法

来源:互联网 发布:淘宝旗舰店假货 编辑:程序博客网 时间:2024/06/11 04:22

问题

  • 默认情况下,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);//获取缓存            ...        }
  • 首先我们要通过 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. 新建一个拦截器

       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;          }      }  })});
    2. 创建一个缓存post数据的容器

       var cache=angular.injector(['ng']).get('$injector').get('$cacheFactory')('$httpPost');
    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          },
    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;          }

代码

  • 完整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>
  • data.json
{  "name":"gyanxie",  "age":"万岁万万岁"}
0 0
原创粉丝点击