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

猜你喜欢

转载自www.cnblogs.com/muamaker/p/11462905.html