javascript写一个ajax自动拦截并下载数据代码实例


Posted in Javascript onSeptember 07, 2019

这篇文章主要介绍了javascript写一个ajax自动拦截并下载数据代码实例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下

代码如下

<!DOCTYPE html>
<html lang="zh">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title></title>
</head>
<body>
</body>
<script type="text/javascript" src="js/jquery-3.3.1.min.js"></script>
<script type="text/javascript">
// 自动下载 ajax 的脚本
;(function($,flag,host){
  if(!flag){
    //如果关闭下载数据,则什么也不做,否则会拦截 ajax 请求返回的数据,进行下载
    return ;
  }
  var ajax = $.ajax; //缓存原始的 ajax
  $.ajax = function(opt){
    var success = opt.success || function(){};
    var url = opt.url || "";
    opt.success = function(res){
      try{
        var name = url.split("?")[0];
        if(host){
          name = name.replace(host,"");
        }
        name = name.replace(/\//g,"_");
        downData(res,`${name}.json`);
      }catch(e){
        console.warn(e);
      }
      success(res);
    }
    return ajax(opt);
  }
  function downData(data,name){
    if(typeof data == "object"){
      data = JSON.stringify(data);
    }
    var blob = new Blob([data], {
     type: 'text/html,charset=UTF-8' 
    });
    window.URL = window.URL || window.webkitURL;
    var a = document.createElement("a");
    a.setAttribute("download",name || "data.json");
    a.href = URL.createObjectURL(blob);
    a.click();
  }
})($,true,"https://www.easy-mock.com");
 
//自动下载数据
$.ajax({
  url:"https://www.easy-mock.com/mock/5bb02bc0a0afc503f502a292/example/demo/secret",
  success(res){
    console.log(res);
  }
})
</script>
</html>

使用原生的 xhr 和fetch 拦截

// 自动下载 ajax 的脚本
  // 命名空间
  window.ajax_interceptor_manny = {
    settings: {
      switchOn: false,
      switchQuery:false
    },
    originalXHR: window.XMLHttpRequest,
    myXHR: function() {
      console.log(" ---ajax 拦截--- ")
      let pageScriptEventDispatched = false;
      const modifyResponse = () => {
        //this.responseText = overrideTxt;
        //this.response = overrideTxt;
        if (pageScriptEventDispatched) {
          return;
        }
        pageScriptEventDispatched = true;
        ajax_interceptor_manny.download(this.responseText, this.responseURL);
      }
 
      // new 一个原生的 XMLHttpRequest 不需要参数,将 xhr 的属性,都复制给this,暴露到外面
      const xhr = new ajax_interceptor_manny.originalXHR();
 
      for (let attr in xhr) {
        if (attr === 'onreadystatechange') {
          xhr.onreadystatechange = (...args) => {
            if (this.readyState == 4 && this.status == 200) {
              // 请求成功
              if (ajax_interceptor_manny.settings.switchOn) {
                // 开启拦截
                modifyResponse();
              }
            }
            this.onreadystatechange && this.onreadystatechange.apply(this, args);
          }
          continue;
        } else if (attr === 'onload') {
          xhr.onload = (...args) => {
            // 请求成功
            if (ajax_interceptor_manny.settings.switchOn) {
              // 开启拦截
              modifyResponse();
            }
            this.onload && this.onload.apply(this, args);
          }
          continue;
        }
 
        if (typeof xhr[attr] === 'function') {
          this[attr] = xhr[attr].bind(xhr);
        } else {
          if (attr === 'responseText' || attr === 'response') {
            var k = "_"+attr;
            Object.defineProperty(this, attr, {
              get: () => this[k] == undefined ? xhr[attr] : this[k],
              set: (val) => this[k] = val,
            });
          } else {
            Object.defineProperty(this, attr, {
              get: () => xhr[attr],
              set: (val) => xhr[attr] = val,
            });
          }
        }
      }
    },
    originalFetch: window.fetch.bind(window),
    myFetch: function(...args) {
      console.log(" ---fetch 拦截--- ")
      return ajax_interceptor_manny.originalFetch(...args).then((response) => {
        if (response.ok) {
          response.clone().text().then((res) => {
            ajax_interceptor_manny.download(res, response.url);
          }).catch((e) => {
            console.warn(e)
          });
        }
        return response;
      });
    },
    download(data, url) {
      try {
        if (ajax_interceptor_manny.settings.switchOn) {
          if (typeof data == "object") {
            data = JSON.stringify(data);
          }
          var blob = new Blob([data], {
            type: 'text/html,charset=UTF-8'
          });
          window.URL = window.URL || window.webkitURL;
 
          var name = url;
          if(!(url.indexOf("http://") >= 0 || url.indexOf("https://") >= 0)){
            //不存在域名
            url = window.origin + url; //手动添加一个,避免URL解析出错
          }
          try {
            var u = new URL(url);
            name = u.pathname;
            var search = u.search.replace("?","");
            if(ajax_interceptor_manny.settings.switchQuery && search){
              //需要带上 get 参数
              name = name + "$"+ search;
            }
          } catch (e) {console.warn(e)}
          name = name.replace(new RegExp("//","g"),"/");
          name = name.replace(new RegExp("/","g"), "_");
          name = name + ".json";
          var a = document.createElement("a");
          a.setAttribute("download", name || "data.json");
          a.href = URL.createObjectURL(blob);
          a.click();
        }
      } catch (e) {
        console.error("下载数据失败", e);
      }
 
    },
 
    setSetting(data) {
      if (typeof data !== "object") {
        return;
      }
      //设置环境
      for (var i in data) {
        ajax_interceptor_manny.settings[i] = data[i];
      }
    },
    init() {
      window.XMLHttpRequest = ajax_interceptor_manny.myXHR;
      window.fetch = ajax_interceptor_manny.myFetch;
    }
  }
ajax_interceptor_manny.init();
ajax_interceptor_manny.setSetting({
  switchOn:true
})

还可以将这个拦截,写为一个浏览插件:

javascript写一个ajax自动拦截并下载数据代码实例

插件代码地址: https://gitee.com/muand/ajaxDown/tree/master/ajaxDown

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
Jquery中LigerUi的弹出编辑框(实现方法)
Jul 09 Javascript
jquery实现的图片点击滚动效果
Apr 29 Javascript
jQuery实现数字加减效果汇总
Dec 16 Javascript
修复bash漏洞的shell脚本分享
Dec 31 Javascript
基于insertBefore制作简单的循环插空效果
Sep 21 Javascript
禁用backspace网页回退功能的实现代码
Nov 15 Javascript
bootstrap datetimepicker日期插件使用方法
Jan 13 Javascript
jQuery使用正则表达式替换dom元素标签用法示例
Jan 16 Javascript
ES6学习之变量的解构赋值
Feb 12 Javascript
vue离开当前页面触发的函数代码
Sep 01 Javascript
VUE和Antv G6实现在线拓扑图编辑操作
Oct 28 Javascript
如何使用JavaScript策略模式校验表单
Apr 29 Javascript
使用layui日期控件laydate对开始和结束时间进行联动控制的方法
Sep 06 #Javascript
解决layer.open后laydate失效的问题
Sep 06 #Javascript
layui的表单验证支持ajax判断用户名是否重复的实例
Sep 06 #Javascript
layui在form表单页面通过Validform加入简单验证的方法
Sep 06 #Javascript
layui自定义验证,用ajax查询后台是否有重复数据,form.verify的例子
Sep 06 #Javascript
layer的prompt弹出框,点击回车,触发确定事件的方法
Sep 06 #Javascript
vue按需加载实例详解
Sep 06 #Javascript
You might like
PHP 和 MySQL 开发的 8 个技巧
2007/01/02 PHP
PHP+shell脚本操作Memcached和Apache Status的实例分享
2016/03/11 PHP
Yii配置与使用memcached缓存的方法
2016/07/13 PHP
RR vs IO BO3 第一场2.13
2021/03/10 DOTA
漂亮的widgets,支持换肤和后期开发新皮肤(2007-4-27已更新1.7alpha)
2007/04/27 Javascript
js下用gb2312编码解码实现方法
2009/12/31 Javascript
js调用iframe实现打印页面内容的方法
2014/03/04 Javascript
Javascript中的回调函数和匿名函数的回调示例介绍
2014/05/12 Javascript
jQuery截取指定长度字符串的实现原理及代码
2014/07/01 Javascript
分享33个jQuery与CSS3实现的绚丽鼠标悬停效果
2014/12/15 Javascript
JavaScript实现常用二级省市级联下拉列表的方法
2015/03/25 Javascript
分享有关jQuery中animate、slide、fade等动画的连续触发、滞后反复执行的bug
2016/01/10 Javascript
js动态获取子复选项并设计全选及提交的实现方法
2016/06/24 Javascript
JavaScript全屏和退出全屏事件总结(附代码)
2017/08/17 Javascript
使用MUI框架模拟手机端的下拉刷新和上拉加载功能
2017/09/04 Javascript
最实用的JS数组函数整理
2017/12/05 Javascript
浅谈Vue Element中Select下拉框选取值的问题
2018/03/01 Javascript
微信小程序实现折线图的示例代码
2019/06/07 Javascript
vue设置一开始进入的页面教程
2019/10/28 Javascript
Vue-cli 移动端布局和动画使用详解
2020/08/10 Javascript
[01:27:43]VGJ.S vs TNC Supermajor 败者组 BO3 第三场 6.6
2018/06/07 DOTA
Python实现栈的方法
2015/05/26 Python
Python算法应用实战之栈详解
2017/02/04 Python
pandas分别写入excel的不同sheet方法
2018/12/11 Python
Python利用Xpath选择器爬取京东网商品信息
2020/06/01 Python
Python类的继承super相关原理解析
2020/10/22 Python
Css3+Js制作漂亮时钟(附源码)
2013/04/24 HTML / CSS
纯CSS3实现鼠标滑过按钮动画第二节
2020/07/16 HTML / CSS
Sneaker Studio波兰:购买运动鞋
2018/04/28 全球购物
店长助理岗位职责
2013/12/13 职场文书
公司周年庆典邀请函
2014/01/12 职场文书
《生命的药方》教学反思
2014/04/08 职场文书
高一学生评语大全
2014/04/25 职场文书
拾金不昧表扬稿
2015/01/16 职场文书
神秘岛读书笔记
2015/07/01 职场文书
Python常用配置文件ini、json、yaml读写总结
2021/07/09 Python