zoukankan      html  css  js  c++  java
  • 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

  • 相关阅读:
    css3 练习
    onethink 返回上一页
    小程序之轮播图
    Node 基本使用
    IDEA Terminal
    Spring Shell简单应用
    Spring Theme简单应用
    Spring MVC的学习笔记
    Win10出现键盘未失灵,按下的键都是快捷键的问题
    SQL Server 添加描述
  • 原文地址:https://www.cnblogs.com/muamaker/p/11462905.html
Copyright © 2011-2022 走看看