AngularJs 拦截器,拦截请求

问题前述

  在项目中遇到这样一个问题:javascript

    在Angular项目中,会有不少须要用户点击操做的地方,若是用户点击过快会产生屡次相同请求,会吃服务器带宽,若是这是其余涉及钱有关的操做,这会产生一个致命的问题。对于这个问题,我想到了两种解决方案:  html

   1. 好比 在点击一个按钮操做的时候,咱们经过将这个按钮 disabled 属性设置为 true ,当请求结束后,再设置为 false ,前端

    代码:    java

html: 缓存

<div class="btn" ng-click="login()" ng-disabled="is_click">登陆</div>

 

Js:  服务器

$scope.login = function(){
//将按钮置为不可点击状态
is_click = true; 

//执行http请求操做
$http({
method : method,
params : params,
url : Config.BASE_URL + url
})
.then(function(){
//请求成功,将按钮置为可点击状态
is_click = false;
})
}

   若是我有不少这样的操做,就须要写不少相同的代码。url

  AngularJs提供了一个拦截器,每次请求在http时,会先到拦截器中。因此,咱们能够在拦截器中采起处理:spa

  1.首先定义一个参数如:is_click, 在须要处理这个操做的地方经过附加这个参数,这样可让咱们去判断这个操做需不须要去检测code

  2.若是有,则进行检测,是否在一秒以内有相同请求(method、url、参数全相同视为相同请求)htm

  3.若是没有,则添加到缓存中,若是有,则取消操做

  具体见代码:

.factory('interceptor', ['$scope', function($scope){
    var requestList = [];    //缓存记录
    function addRequestList(url){     //插入记录
    var keepGoing = true;
      angular.forEach(requestList, function (item) {
        if(keepGoing && item.name == url){
          item.time = new Date().getTime();
          keepGoing = false;
        }
      });

      if(keepGoing){
        requestList.push({
          name: url,
          time: new Date().getTime()
        });
      }
    }
    function hitRequestList(url) {    //检测是否有记录,并返回时间
    var time = '';
      var keepGoing = true;
      angular.forEach(requestList, function (item) {
        if(keepGoing && item.name == url){
          time = item.time;
          keepGoing = false;
        }
      });
      return time;
    }
     //method,url,data 拼接成 string
    function getRequestKey(data) {
      var key = 'method:' + data.method + ',url:' + data.url + ',data:';
      var str = '';

      //特殊处理
        ...

      return key += str ? str : JSON.stringify(data.params || {});
    }
     var _interceptor = {
          'request': function(req) {
            if (req.params && req.params.is_click) {
              var key = getRequestKey(req);
              var lastTime = hitRequestList(key);      //上次请求时间
              var requesTime = new Date().getTime();   //当前请求时间
              if (lastTime && ((requesTime - lastTime) < 1000)) {
                console.log('----------', '取消此次请求');
                req.method = 'GET';
                req.cache = {
                  get: function () {
                    return null;
                  }
                };
              }
              addRequestList(key);
            }
        return _interceptor
}])        

  最主要的取消请求的代码: 

 

        req.method = 'GET';
                req.cache = {
                  get: function () {
                    return null;
                  }
                };


总结:
  做为前端小学生,第一次写文章,难免有些错误的地方,但愿你们能够提出来,感谢。
相关文章
相关标签/搜索