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;
						if(ajax_interceptor_manny.settings.switchQuery){
							//需要带上 get 参数
							name = name + "$"+ u.search.replace("?","");
						}
					} catch (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
});

  

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

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

原文地址:https://www.cnblogs.com/muamaker/p/11462905.html

时间: 2024-12-28 18:14:12

javascript 写一个ajax 自动拦截,并下载数据的相关文章

写一个ajax程序就是如此简单

写一个ajax程序就是如此简单 ajax介绍: 1:AJAX全称为Asynchronous JavaScript and XML(异步JavaScript和XML),指一种创建交互式网页应用的网页开发技术.     2:基于web标准XHTML+CSS的表示:     3:使用 DOM进行动态显示及交互:     4:使用 XML 和 XSLT 进行数据交换及相关操作:     5:使用 XMLHttpRequest 进行异步数据查询.检索: 程序员应用ajax的途经: 1:.Net下的Ajax

写一个ajax请求出现的问题

今天在写一个ajax请求的时候出现ajax请求成功后,页面居然会出现刷新,url有跳转,找了半天,终于发现了问题所在,原来我在表单里面有一个 <input type="button" onclick="submit()"/>元素,之前用的是表单提交的方式发送的请求,改成ajax请求后忘记删除,但是我好奇的是我在js里面写的submit()方法已经被删除了,怎么还会提交表单呢?我仔细一看,原来button的onclick事件触发的submit()方法还是会

编译原理实战入门:用 JavaScript 写一个简单的四则运算编译器(四)结语

四则运算编译器,虽然说功能很简单,只能编译四则运算表达式.但是编译原理前端部分几乎都有涉及,词法分析,语法分析,还有代码生成. 再复杂的编译器.再简单的编译器,功能上是差不多的,只是复杂的编译器实现上会更困难. 这个系列的文章是为了帮助你入门,在这个基础上再去看编译原理相关书籍,不至于打瞌睡. 如果你对编译原理很有兴趣,并且想更深一步的学习,在这里强烈推荐你看一本书--我心目中的神书--<计算机系统要素-从零开始构建现代计算机>. 这本书神在哪? 神在它通俗易懂,对小白足够友好,但又不过分肤浅

Individual Project &quot;写一个能自动生成小学四则运算题目的程序&quot;

一.题目简介 写一个能自动生成小学四则运算题目的程序. 初步拟定要实现的功能后,估计一下自己需要花多长时间.编程过程中记录自己实际用了多长时间. 然后和同学们比较一下各自程序的功能.实现方法的异同等等. 二.源码的github链接 https://github.com/gaino1/IndividualProject 三.所设计的模块测试用例.测试结果截图 四.问题及解决方案.心得体会 要想学好C语言,要重在实践,要通过不断的上机操作才能更好地学习它,通过实践,我也发现我的好多不足之处,首先是自

JavaScript写一个连连看的游戏

天天看到别人玩连连看, 表示没有认真玩过, 不就把两个一样的图片连接在一起么, 我自己写一个都可以呢. 使用Javascript写了一个, 托管到github, 在线DEMO地址查看:打开 最终的效果图: 写连连看之前要先考虑哪些呢? 1:如何判断两个元素可以连接呢, 刚刚开始的时候我也纳闷, 可以参考这里:打开: 2:模板引擎怎么选择呢, 我用了底线库的template,因为语法简单. 本来想用Handlebars,但是这个有点大啊, 而且底线库也提供很多常用工具方法( •? ω •? )y:

用javascript写一个前端等待控件

前端等待控件有啥新奇的?什么jquery啦,第三方控件啦,好多好多,信手拈来. 因为项目使用了bootstrap的原因,不想轻易使用第三方,怕不兼容.自己写一个. 技术点包括动态加载CSS,javascript的命名空间,所以记录一下. 这个等待控件主要是:进行某个操作前,显示一个信息提示:"数据加载中,请稍候...",操作成功后,在回调函数中将提示消失. 原理是这个等待控件完全由JS动态加进去,包括CSS,页面中并无预先设定. 那么这个CSS怎么动态加载呢?等待控件中,样式使用了cl

JavaScript写一个小乌龟推箱子游戏

推箱子游戏是老游戏了, 网上有各种各样的版本, 说下推箱子游戏的简单实现,以及我找到的一些参考视频和实例: 推箱子游戏的在线DEMO : 打开 如下是效果图: 这个拖箱子游戏做了移动端的适配, 我使用了zepto的touch模块, 通过手指滑动屏幕就可以控制乌龟走不同的方向: 因为推箱子这个游戏比较简单, 直接用了过程式的方式写代码, 模块也就是两个View 和 Model, 剩下就是用户的事件Controller, 用户每一次按下键盘的方向键都会改变数据模型的数据,然后重新生成游戏的静态htm

原生javascript包装一个ajax方法

调用AJAX 1 <script type="text/javascript" src="ajax.js"></script> 2 <script type="text/javascript"> 3 //调用包装好的ajax方法 4 ajax({ 5 method : "get", 6 url : "get.php", 7 asyn : true, 8 data : &q

JavaScript写一个拼图游戏

拼图游戏的代码400行, 有点多了, 在线DEMO的地址是:打开: 因为使用canvas,所以某些浏览器是不支持的: you know: 为什么要用canvas(⊙o⊙)?  因为图片是一整张jpg或者png, 我们要用把图片导入到canvas画布, 然后再调用上下文context的getImageData方法, 把图片处理成小图, 这些小图就作为拼图的基本单位: 如何判断游戏是否结束, 或者说如何判断用户拼成的大图是正确的? 我们就要在刚刚生成的小图上面添加自定义属性, 后期在小图被移动后再一