需求
1、前端请求为了安全考虑都是经过加密处理,不论接口地址还是请求参数,或者返回数据
2、安全性是解决了,但是开发测试找问题时就很麻烦,看不到数据
3、开发油猴插件,拦截请求,解密数据就能达到目的
方法
1、重写 XMLHttpRequest.prototype.open 代理 get 请求
2、重写 XMLHttpRequest.prototype.send 代理 post 请求
脚本
// ==UserScript==
// @name 解密助手
// @namespace http://tampermonkey.net/
// @version 0.1
// @description try to take over the world!
// @author You
// @match *
// @icon https://www.google.com/s2/favicons?sz=64&domain=baidu.com
// @grant GM_setValue
// @grant GM_getValue
// @grant GM_setClipboard
// @grant GM_getClipboard
// @grant GM_notification
// @grant GM_xmlhttpRequest
// @grant GM_download
// ==/UserScript==
(function () {
"use strict";
// 工具方法
const Utils = {
getQueryVariable(url, variable) {
var query = url.split("?")[1];
if (!query) return "";
var vars = query.split("&");
for (var i = 0; i < vars.length; i++) {
var pair = vars[i].split("=");
if (pair[0] == variable) {
return pair[1];
}
}
return "";
},
log(name, value) {
console.info(`%c ${name}`, "color: #23f10a", value);
},
notification(text, timeout = 3000) {
GM_notification({
text,
title: "通知",
timeout,
});
},
set(name, value) {
GM_setValue(
name,
typeof value == "string" ? value : JSON.stringify(value)
);
},
get(name, value) {
return GM_getValue(name, value);
},
async wait(time = 1000) {
await new Promise((resolve) => setTimeout(resolve, time));
},
debounce(fn, timestamp = 1000) {
let go = true;
return () => {
if (!go) return;
go = false;
fn();
go = true;
};
},
};
// 解密
const ConsoleEncrypt = {
decryptResponseData(encryptString) {
// 自定解密过程 密文 -> 明文
return encryptString;
},
};
// http代理
// 重写open https://developer.mozilla.org/zh-CN/docs/Web/API/XMLHttpRequest/open
// 重写send https://developer.mozilla.org/zh-CN/docs/Web/API/XMLHttpRequest/send
XMLHttpRequest.prototype.myOpen2 = XMLHttpRequest.prototype.open;
XMLHttpRequest.prototype.mySend2 = XMLHttpRequest.prototype.send;
const HttpProxy = {
beforeXMLHttpRequestOpen() {
XMLHttpRequest.prototype.open = function (
method,
url,
async,
user,
password
) {
try {
if (method.toUpperCase() == "GET") {
const encryptString = Utils.getQueryVariable(url, "encryptString");
if (encryptString) {
const decryptObject = ConsoleEncrypt.decryptResponseData(
decodeURIComponent(encryptString)
);
// 打印解密数据
console.log("解密请求GET", url, decryptObject);
}
}
} catch (e) {}
// 触发原请求
this.myOpen2(method, url, async, user, password);
};
},
beforeXMLHttpRequestSend() {
XMLHttpRequest.prototype.send = function (body) {
try {
if (body) {
const bodyObject = JSON.parse(body);
const decryptObject = ConsoleEncrypt.decryptResponseData(
decodeURIComponent(bodyObject.encryptString)
);
// 打印解密数据
console.log(
"解密请求POST",
this.responseURL?.replace(/^http(s):\/\/[a-zA-Z0-9\.-]+/, ""),
decryptObject
);
}
} catch (e) {}
this.mySend2(body);
};
},
};
// 程序启动
HttpProxy.beforeXMLHttpRequestOpen();
HttpProxy.beforeXMLHttpRequestSend();
})();