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 相关文章推荐
关于使用runtimeStyle属性问题讨论文章
Mar 08 Javascript
js操纵dom生成下拉列表框的方法
Feb 24 Javascript
常见浏览器多长时间会提示“脚本运行时间过长”总结
Apr 29 Javascript
JS实现闪动的title消息提醒效果
Jun 20 Javascript
Javascript中封装window.open解决不兼容问题
Sep 28 Javascript
JS实现仿中关村论坛评分后弹出提示效果的方法
Feb 23 Javascript
jQuery中extend函数详解
Jul 13 Javascript
AngularJs 最新验证手机号码的实例,成功测试通过
Nov 26 Javascript
基于jquery trigger函数无法触发a标签的两种解决方法
Jan 06 jQuery
解决Angularjs异步操作后台请求用$q.all排列先后顺序问题
Nov 29 Javascript
JS实现滑动导航效果
Jan 14 Javascript
VueQuillEditor富文本上传图片(非base64)
Jun 03 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 date函数参数详解
2006/11/27 PHP
晋城吧对DiscuzX进行的前端优化要点
2010/09/05 PHP
php限制ip地址范围的方法
2015/03/31 PHP
Js callBack 返回前一页的js方法
2008/11/30 Javascript
javascript 类定义的4种方法
2009/09/12 Javascript
Jquery 改变radio/checkbox选中状态,获取选中的值(示例代码)
2013/12/12 Javascript
jQuery中data()方法用法实例
2014/12/27 Javascript
JavaScript中SetInterval与setTimeout的用法详解
2015/11/10 Javascript
Bootstrap框架的学习教程详解(二)
2016/10/18 Javascript
基于javascript实现的快速排序
2016/12/02 Javascript
jquery的父、子、兄弟节点查找,节点的子节点循环方法
2016/12/07 Javascript
Angular.js基础学习之初始化
2017/03/10 Javascript
使用angular帮你实现拖拽的示例
2017/07/05 Javascript
vue 实现通过手机发送短信验证码注册功能
2018/04/19 Javascript
用js限制网页只在微信浏览器中打开(或者只能手机端访问)
2020/12/24 Javascript
Python中的包和模块实例
2014/11/22 Python
Python根据区号生成手机号码的方法
2015/07/08 Python
基于Python实现一个简单的银行转账操作
2016/03/06 Python
Sanic框架蓝图用法实例分析
2018/07/17 Python
Python3 pip3 list 出现 DEPRECATION 警告的解决方法
2019/02/16 Python
python3射线法判断点是否在多边形内
2019/06/28 Python
django获取from表单multiple-select的value和id的方法
2019/07/19 Python
基于python的itchat库实现微信聊天机器人(推荐)
2019/10/29 Python
tensorflow如何继续训练之前保存的模型实例
2020/01/21 Python
Python实现获取当前目录下文件名代码详解
2020/03/10 Python
python 生成任意形状的凸包图代码
2020/04/16 Python
解决reload(sys)后print失效的问题
2020/04/25 Python
pycharm 如何取消连按两下shift出现的全局搜索
2021/01/15 Python
Moda Italia荷兰:意大利男士服装
2019/08/31 全球购物
工作会议欢迎词
2014/01/16 职场文书
关工委先进个人事迹材料
2014/05/23 职场文书
习近平在党的群众路线教育实践活动总结大会上的讲话
2014/10/21 职场文书
《观潮》教学反思
2016/02/17 职场文书
怎样写工作总结啊!
2019/06/18 职场文书
大学生各类奖学金申请书
2019/06/24 职场文书
长辈生日祝福语大全(72句)
2019/08/09 职场文书