• 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
    })
    

      

      

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

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

  • 相关阅读:
    POJ 1611 The Suspects
    POJ 2001 Shortest Prefixes(字典树)
    HDU 1251 统计难题(字典树 裸题 链表做法)
    G++ C++之区别
    PAT 乙级 1013. 数素数 (20)
    PAT 乙级 1012. 数字分类 (20)
    PAT 乙级 1009. 说反话 (20)
    PAT 乙级 1008. 数组元素循环右移问题 (20)
    HDU 6063 17多校3 RXD and math(暴力打表题)
    HDU 6066 17多校3 RXD's date(超水题)
  • 原文地址:https://www.cnblogs.com/muamaker/p/11462905.html
Copyright © 2020-2023  润新知