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 相关文章推荐
JS仿flash上传头像效果实现代码
Jul 18 Javascript
获取div编辑框,textarea,input text的光标位置 兼容IE,FF和Chrome的方法介绍
Nov 08 Javascript
Javascript中的for in循环和hasOwnProperty结合使用
Jun 05 Javascript
调用HttpHanlder的几种返回方式小结
Dec 20 Javascript
jquery实现图片翻页效果
Dec 23 Javascript
jQuery移动页面开发中的触摸事件与虚拟鼠标事件简介
Dec 03 Javascript
javascript完美实现给定日期返回上月日期的方法
Jun 15 Javascript
js实现图片旋转 js滚动鼠标中间对图片放大缩小
Jul 05 Javascript
vue-cli项目优化方法- 缩短首屏加载时间
Apr 01 Javascript
在vue项目中引入highcharts图表的方法
Jan 21 Javascript
VuePress 静态网站生成方法步骤
Feb 14 Javascript
Vue 刷新当前路由的实现代码
Sep 26 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中用正则表达式清除字符串的空白
2011/01/17 PHP
关于shopex同步ucenter的redirect问题,导致script不运行
2013/04/10 PHP
9个经典的PHP代码片段分享
2014/12/18 PHP
php生成图片验证码
2015/06/09 PHP
Laravel日志用法详解
2016/10/09 PHP
php 可变函数使用小结
2018/06/12 PHP
php-fpm超时时间设置request_terminate_timeout资源问题分析
2019/09/27 PHP
Laravel-添加后台模板AdminLte的实现方法
2019/10/08 PHP
JavaScript 语言基础知识点总结(思维导图)
2013/11/10 Javascript
XMLHttpRequest处理xml格式的返回数据(示例代码)
2013/11/21 Javascript
JavaScript使用指针操作实现约瑟夫问题实例
2015/04/07 Javascript
JavaScript省市级联下拉菜单实例
2017/02/14 Javascript
Vuejs仿网易云音乐实现听歌及搜索功能
2017/03/30 Javascript
Angular2 父子组件数据通信实例
2017/06/22 Javascript
Vue.js 的移动端组件库mint-ui实现无限滚动加载更多的方法
2017/12/23 Javascript
深入了解JavaScript 的 WebAssembly
2019/06/15 Javascript
js+springMVC 提交数组数据到后台的实例
2019/09/21 Javascript
python使用in操作符时元组和数组的区别分析
2015/05/19 Python
python字符串对其居中显示的方法
2015/07/11 Python
详解python调度框架APScheduler使用
2017/03/28 Python
python/sympy求解矩阵方程的方法
2018/11/08 Python
python 处理数字,把大于上限的数字置零实现方法
2019/01/28 Python
Python面向对象程序设计中类的定义、实例化、封装及私有变量/方法详解
2019/02/28 Python
使用python+whoosh实现全文检索
2019/12/09 Python
Python利用逻辑回归模型解决MNIST手写数字识别问题详解
2020/01/14 Python
Python如何使用PIL Image制作GIF图片
2020/05/16 Python
matplotlib 多个图像共用一个colorbar的实现示例
2020/09/10 Python
用纯css3和html制作泡沫对话框实现代码
2013/03/21 HTML / CSS
德国珠宝和手表在线商店:VALMANO
2019/03/24 全球购物
大学生职业生涯设计书
2014/01/02 职场文书
优秀教师感人事迹材料
2014/05/04 职场文书
激励员工的口号
2014/06/16 职场文书
五年级上册复习计划
2015/01/19 职场文书
催款通知书范文
2015/04/17 职场文书
盗窃案辩护词
2015/05/21 职场文书
Go语言基础函数基本用法及示例详解
2021/11/17 Golang