问题前述

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

    在Angular项目中,会有很多需要用户点击操作的地方,如果用户点击过快会产生多次相同请求,会吃服务器带宽,如果这是其他涉及钱有关的操作,这会产生一个致命的问题。对于这个问题,我想到了两种解决方案:  

   1. 比如 在点击一个按钮操作的时候,我们通过将这个按钮 disabled 属性设置为 true ,当请求结束后,再设置为 false ,

    代码:    

html: 

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

Js:  

  1. $scope.login = function(){
  2. //将按钮置为不可点击状态
  3. is_click = true;
  4.  
  5. //执行http请求操作
  6. $http({
  7. method : method,
  8. params : params,
  9. url : Config.BASE_URL + url
  10. })
  11. .then(function(){
  12. //请求成功,将按钮置为可点击状态
  13. is_click = false;
  14. })
  15. }

   如果我有很多这样的操作,就需要写很多相同的代码。

  AngularJs提供了一个拦截器,每次请求在http时,会先到拦截器中。所以,我们可以在拦截器中采取处理:

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

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

  3.如果没有,则添加到缓存中,如果有,则取消操作

  具体见代码:

  1. .factory('interceptor', ['$scope', function($scope){
  2. var requestList = []; //缓存记录
  3. function addRequestList(url){ //插入记录
  4. var keepGoing = true;
  5. angular.forEach(requestList, function (item) {
  6. if(keepGoing && item.name == url){
  7. item.time = new Date().getTime();
  8. keepGoing = false;
  9. }
  10. });
  11.  
  12. if(keepGoing){
  13. requestList.push({
  14. name: url,
  15. time: new Date().getTime()
  16. });
  17. }
  18. }
  19. function hitRequestList(url) { //检测是否有记录,并返回时间
  20. var time = '';
  21. var keepGoing = true;
  22. angular.forEach(requestList, function (item) {
  23. if(keepGoing && item.name == url){
  24. time = item.time;
  25. keepGoing = false;
  26. }
  27. });
  28. return time;
  29. }
  30. //method,url,data 拼接成 string
  31. function getRequestKey(data) {
  32. var key = 'method:' + data.method + ',url:' + data.url + ',data:';
  33. var str = '';
  34.  
  35. //特殊处理
  36. ...
  37.  
  38. return key += str ? str : JSON.stringify(data.params || {});
  39. }
  40. var _interceptor = {
  41. 'request': function(req) {
  42. if (req.params && req.params.is_click) {
  43. var key = getRequestKey(req);
  44. var lastTime = hitRequestList(key); //上次请求时间
  45. var requesTime = new Date().getTime(); //当前请求时间
  46. if (lastTime && ((requesTime - lastTime) < 1000)) {
  47. console.log('----------', '取消这次请求');
  48. req.method = 'GET';
  49. req.cache = {
  50. get: function () {
  51. return null;
  52. }
  53. };
  54. }
  55. addRequestList(key);
  56. }
  57. return _interceptor
  58. }])

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

  1.         req.method = 'GET';
  2. req.cache = {
  3. get: function () {
  4. return null;
  5. }
  6. };
  7.  
  8. 总结:
      作为前端小学生,第一次写文章,不免有些错误的地方,希望大家可以提出来,感谢。

AngularJs 拦截器,拦截请求的更多相关文章

  1. Java过滤器处理Ajax请求,Java拦截器处理Ajax请求,拦截器Ajax请求

    Java过滤器处理Ajax请求,Java拦截器处理Ajax请求,拦截器Ajax请求 >>>>>>>>>>>>>>&g ...

  2. spring mvc 通过拦截器记录请求数据和响应数据

    spring mvc 能过拦截器记录请求数据记录有很多种方式,主要有以下三种: 1:过滤器 2:HandlerInterceptor拦截器 3:Aspect接口控制器 但是就我个人所知要记录返回的数据 ...

  3. Springboot通过拦截器拦截请求信息收集到日志

    1.需求 最近在工作中遇到的一个需求,将请求中的客户端类型.操作系统类型.ip.port.请求方式.URI以及请求参数值收集到日志中,网上找资料说用拦截器拦截所有请求然后收集信息,于是就开始了操作: ...

  4. Struts2 拦截器—拦截action

    对于拦截器的基本使用这里我就懒得打字了,我这里就讲下如何用 Struts2 拦截器 拦截action.这是我个人的想法,如果有什么不对的,或者你们有什么更好的方法.请多多留言! 拦截器的默认拦截的方法 ...

  5. 防止SpringMVC拦截器拦截js等静态资源文件

    SpringMVC提供<mvc:resources>来设置静态资源,但是增加该设置如果采用通配符的方式增加拦截器的话仍然会被拦截器拦截,可采用如下方案进行解决: 方案一.拦截器中增加针对静 ...

  6. Springboot前后端分离中,后端拦截器拦截后,前端没有对应的返回码可以判断

    项目登录流程如下 用户进入前端登录界面,输入账号密码等,输入完成之后前端发送请求到后端(拦截器不会拦截登录请求),后端验证账号密码等成功之后生成Token并存储到数据库,数据库中包含该Token过期时 ...

  7. Structs2 中拦截器获取请求参数

    前言 环境:window 10,JDK 1.7,Tomcat 7 测试代码 package com.szxy.interceptor; import java.util.Map; import jav ...

  8. springboot springmvc拦截器 拦截POST、PUT、DELETE请求参数和响应数据,并记录操作日志

    1.操作日志实体类 @Document(collection = "operation_log") @Getter @Setter @ToString public class O ...

  9. vue 路由拦截器和请求拦截器

    路由拦截器 已路由为导向 router.beforeEach((to,from,next)=>{ if(to.path=='/login' || localStorage.getItem('to ...

  10. Apache httpclient拦截器对请求进行签名

    Apahce httpclient 提供HttpRequestInterceptor和HttpResponseInterceptor两种拦截器分别处理请求和响应数据,下面讲一下如何对http请求进行拦 ...

随机推荐

  1. 复习二叉数 pat l2-006 数的遍历

    L2-006. 树的遍历   给定一棵二叉树的后序遍历和中序遍历,请你输出其层序遍历的序列.这里假设键值都是互不相等的正整数. 输入格式: 输入第一行给出一个正整数N(<=30),是二叉树中结点 ...

  2. Qt调用VS生成的dll

      预备知识: 1.如果在没有导入库文件(.lib),而只有头文件(.h)与动态链接库(.dll)时,我们才需要显示调用,如果这三个文件都全的话,我们就可以使用简单方便的隐式调用. 2.通常Windo ...

  3. 【图像处理 】 一、OSTU分割法

    图像中像素的灰度值小于阈值T的像素个数记作N0,像素灰度大于阈值T的像素个数记作N1,则有: 图像大小:M*N T为二值化的阈值: N0为灰度小于T的像素的个数,N0的平均灰度为μ0 N1 为灰度大于 ...

  4. mysql管理工具之pt

    之前我一直用Seconds_behind_master来衡量主从的延迟,今天看到文档,才觉得多么不可靠!以下是官方文档的描述: In essence, this field measures the ...

  5. Spring Cloud(十一)高可用的分布式配置中心 Spring Cloud Bus 消息总线集成(RabbitMQ)

    详见:https://www.w3cschool.cn/spring_cloud/spring_cloud-jl8a2ixp.html 上一篇文章,留了一个悬念,Config Client 实现配置的 ...

  6. host文件简介及修改后不能保存解决方法

    一.文件概述 Hosts是一个没有扩展名的系统文件,可以用记事本等工具打开,其作用就是将一些常用的网址域名与其对应的IP地址建立一个关联“数据库”,当用户在浏览器中输入一个需要登录的网址时,系统会首先 ...

  7. Centos7虚拟机根分区扩展

    线上的kvm虚拟机,原来只规划了8G,后来发现硬盘动不动就被日志塞满了,需要进行扩容. 扩容步骤如下: 1.先把kvm虚拟机关机 2.在宿主机上进行kvm虚拟机的磁盘扩容 qemu-img resiz ...

  8. rdb和aof二种持久化方式对比(Redis)

    我们已经知道对于一个企业级的redis架构来说,持久化是不可减少的 企业级redis集群架构:海量数据.高并发.高可用 持久化主要是做灾难恢复,数据恢复,也可以归类到高可用的一个环节里面去 比如你re ...

  9. anaconda环境中---py2.7下安装tf1.0 + py3.5下安装tf1.5

    anaconda环境中---py2.7下安装tf1.0 + py3.5下安装tf1.5 @wp20181030 环境:ubuntu18.04, anaconda2, ubuntu系统下事先安装了pyt ...

  10. fixed固定元素

    1.css <style type="text/css"> .elementFixed{ position: fixed; top:0; } </style> ...