油猴脚本xmlhttprequest劫持及原理解释

源代码出自 https://scriptcat.org/script-show-page/47/code

以下内容是对代码的一个解释

      // ==UserScript==
      // @name         xhr
      // @namespace    http://tampermonkey.net/
      // @version      0.1
      // @description  try to take over the world!
      // @author       You
      // @match        http://*/*
      // @match        https://www.baidu.com/
      // @match        https://so.csdn.net/*/*
      // @grant        none
      // ==/UserScript==

      (function () {
        "use strict";

        //劫持函数
        function addXMLRequestCallback(callback) {
          // oldSend 旧函数 i 循环
          var oldSend, i;
          //判断是否有callbacks变量
          if (XMLHttpRequest.callbacks) {
            //判断XMLHttpRequest对象下是否存在回调列表,存在就push一个回调的函数
            XMLHttpRequest.callbacks.push(callback);
          } else {
            //如果不存在则在xmlhttprequest函数下创建一个回调列表/callback数组
            XMLHttpRequest.callbacks = [callback];
            // 保存 XMLHttpRequest 的send函数
            oldSend = XMLHttpRequest.prototype.send;
            //获取旧xml的send函数,并对其进行劫持(替换)  function()则为替换的函数
            //以下function函数是一个替换的例子
            XMLHttpRequest.prototype.send = function () {
              // 把callback列表上的所有函数取出来
              for (i = 0; i < XMLHttpRequest.callbacks.length; i++) {
                // 把this传入进去
                XMLHttpRequest.callbacks[i](this);
              }
              //循环回调xml内的回调函数
              // 调用旧的send函数 并传入this 和 参数
              oldSend.apply(this, arguments);
              //由于我们获取了send函数的引用,并且复写了send函数,这样我们在调用原send的函数的时候,需要对其传入引用,而arguments是传入的参数
            };
          }
        }

        // e.g.
        //传入回调 接收xhr变量
        addXMLRequestCallback(function (xhr) {
          //调用劫持函数,填入一个function的回调函数
          //回调函数监听了对xhr调用了监听load状态,并且在触发的时候再次调用一个function,进行一些数据的劫持以及修改
          xhr.addEventListener("load", function () {
            // 输入xhr所有相关信息
            console.log(xhr);
            if (xhr.readyState == 4 && xhr.status == 200) {
              //  如果xhr请求成功 则返回请求路径
              console.log("函数1", xhr.responseURL);
            }
          });
        });

        // Your code here...
      })();
XHR劫持是以csdn搜索页面为例子

上述代码开启插件后,运行之后页面还是正常状态,控制台会输出xhr请求的路径,如下:

接下来是劫持网页原本发出的请求,替换成自己的数据:
// ==UserScript==
// @name         xhr拦截
// @namespace    http://tampermonkey.net/
// @version      0.1
// @description  try to take over the world!
// @author       You
// @match        http://*/*
// @match        https://www.baidu.com/
// @match        https://so.csdn.net/*/*
// @grant        none
// ==/UserScript==

(function() {
    'use strict';

    function addXMLRequestCallback(callback){
        //debugger;
        //是一个劫持的函数
        // oldSend 旧函数 i 循环
        var oldSend, i;
        //判断是否有callbacks变量
        if( XMLHttpRequest.callbacks ) {
            //判断XMLHttpRequest对象下是否存在回调列表,存在就push一个回调的函数
            XMLHttpRequest.callbacks.push( callback );
        } else {
            //如果没有则创建一个callback数组  //如果不存在则在xmlhttprequest函数下创建一个回调列表
            XMLHttpRequest.callbacks = [callback];
            // 保存 XMLHttpRequest 的send函数
            oldSend = XMLHttpRequest.prototype.send;

            //获取旧xml的send函数,并对其进行劫持(替换)  function()则为替换的函数
            XMLHttpRequest.prototype.send = function(){

                // 这里进行一些对自己数据的操作
                
                // 发送请求
                fetch("https://api.apiopen.top/api/getImages?type=animal&page=1&size=10")
                    .then(response=> response.json())
                    .then(result =>{

                    //获取被替换的dom
                    const dom = document.getElementsByClassName("main-lt")[0];
                    dom.innerHTML = result.result.list[0].title

                })
                //循环回调xml内的回调函数
                // 调用旧的send函数 并传入this 和 参数
                oldSend.apply(this, arguments);
                //oldSend.apply(1);
                //由于我们获取了send函数的引用,并且复写了send函数,这样我们在调用原send的函数的时候,需要对其传入引用,而arguments是传入的参数
            }
        }
    }

    // e.g.
    //传入回调 接收xhr变量
    addXMLRequestCallback( function( xhr ) {
        //调用劫持函数,填入一个function的回调函数
        //回调函数监听了对xhr调用了监听load状态,并且在触发的时候再次调用一个function,进行一些数据的劫持以及修改
        //对xhr进行事件监听 判断是load 再回调function函数
        xhr.addEventListener("load", function(){
            console.log(xhr)
            if ( xhr.readyState == 4 && xhr.status == 200 ) {
                // 输入当前的路径
                console.log( '函数1',xhr.responseURL );
            }
        });

    });


    // Your code here...
})();
结果如下:

  • 13
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

吞掉星星的鲸鱼

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值