angular 缓存post请求的方法

    xiaoxiao2021-04-13  28

    问题

    默认情况下,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请求。所以第一次请求,必须原封不动的发给后台。这就导致了,我们只能自己创建一个容器来缓存数据。并且是 cacheFactory http才能识别。

    方法

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

    思路

    新建一个拦截器

    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; } } }) });

    创建一个缓存post数据的容器

    var cache=angular.injector(['ng']).get('$injector').get('$cacheFactory')('$httpPost');

    在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 },

    在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":"万岁万万岁" }
    转载请注明原文地址: https://ju.6miu.com/read-668983.html

    最新回复(0)