xiaoxigithub 发表于 2024-8-5 17:36:25

分享一个XMLHttpRequest网络数据包拦截分析

本帖最后由 xiaoxigithub 于 2024-8-5 17:40 编辑

主要是对XMLHttpRequest构造函数做了重写实现,可以修改目标网页发起任意请求前和响应后的数据。
> 仅做学习研究,修改请求和响应数据时,需要遵循相关网站的使用政策和法律法规。

**不说废话直接上代码:**
```
// ==UserScript==
// @name         测试XMLHttpRequest Interceptor
// @namespace    http://tampermonkey.net/
// @version      2024-08-05
// @description拦截和修改 XMLHttpRequest 的请求和响应例子
// @author       You
// @match      https://www.example.com/*
// @grant      none
// ==/UserScript==

(function () {
    'use strict';

    // 保存原始的 XMLHttpRequest 构造函数
    const originalXHR = window.XMLHttpRequest;

    // 重写 XMLHttpRequest 构造函数
    function newXHR() {
      const xhr = new originalXHR();

      // 保存原始的 open 方法
      const originalOpen = xhr.open;
      xhr.open = function (method, url, async, user, password) {
            // 修改URL,添加参数
            const newUrl = new URL(url, window.location.origin);
            newUrl.searchParams.append('extraParam', 'extraValue');

            console.log('Modified URL:', newUrl.toString());
            // 调用原始的 open 方法
            originalOpen.apply(xhr, );
      };

      // 保存原始的 send 方法
      const originalSend = xhr.send;
      xhr.send = function (body) {
            // 这里可以拦截和修改请求数据
            console.log('Request Body:', body);
            // 调用原始的 send 方法
            originalSend.apply(xhr, arguments);
      };

      // 监听 readyState 的变化
      xhr.addEventListener('readystatechange', function () {
            if (xhr.readyState === 4) {
                // 这里可以拦截和修改响应数据
                console.log('Response Status:', xhr.status);
                console.log('Response responseType:', xhr.responseType);
                if (xhr.responseType != 'arraybuffer' && xhr.responseURL.includes('action=GetNetWork')) {
                  var parse_data = JSON.parse(xhr.responseText);
                  parse_data['time'] = '测试' + parse_data['time']; // 修改响应数据
                  parse_data['title'] = '测试' + parse_data['title']; // 修改响应数据
                  console.log('Response Data:', parse_data);
                  // 如果需要修改响应,可以创建一个新的 Response 对象
                  const modifiedResponse = JSON.stringify(parse_data);
                  Object.defineProperty(xhr, 'responseText', { value: modifiedResponse });

                  // 将修改后的响应数据发送到本地服务器
                  sendToLocalServer(modifiedResponse);
                }

            }
      }, false);

      return xhr;
    }

    // 替换全局的 XMLHttpRequest 构造函数
    window.XMLHttpRequest = newXHR;

    // 发送数据到本地服务器
    function sendToLocalServer(data) {
      const xhr = new XMLHttpRequest();
      xhr.open('POST', 'http://localhost:9501/index/index', true);
      xhr.setRequestHeader('Content-Type', 'application/json;charset=UTF-8');
      xhr.onreadystatechange = function () {
            if (xhr.readyState === 4 && xhr.status === 200) {
                console.log('Data sent to local server successfully');
            }
      };
      xhr.send(data);
    }

})();
```

另外附效果图,从目标网站拦截数据包后上传到服务器做数据分析
!(data/attachment/forum/202408/05/174047hd0jt98ewjeivqgh.jpg)

李恒道 发表于 2024-8-6 01:38:44

哥哥可以试试https://bbs.tampermonkey.net.cn/thread-3284-1-1.html
还是挺方便的

yhzc2023 发表于 2024-8-6 20:56:21

李恒道 发表于 2024-8-6 01:38
哥哥可以试试https://bbs.tampermonkey.net.cn/thread-3284-1-1.html
还是挺方便的

哥哥啊,通过 @require 这种方法注入脚本是不是会延后执行脚本的时刻?

王一之 发表于 2024-8-7 09:46:30

yhzc2023 发表于 2024-8-6 20:56
哥哥啊,通过 @require 这种方法注入脚本是不是会延后执行脚本的时刻?

不会的,和脚本一起注入执行

xiaoxigithub 发表于 2024-8-7 09:54:06

李恒道 发表于 2024-8-6 01:38
哥哥可以试试https://bbs.tampermonkey.net.cn/thread-3284-1-1.html
还是挺方便的

好的,初来乍到向哥哥们学习{:4_108:}

yhzc2023 发表于 2024-8-7 10:45:10

王一之 发表于 2024-8-7 09:46
不会的,和脚本一起注入执行

使用 @require 不是请求完成后再开始执行后续的脚本?这样的话,相对去没有 @require 的不就是延后了?

王一之 发表于 2024-8-7 11:54:28

yhzc2023 发表于 2024-8-7 10:45
使用 @require 不是请求完成后再开始执行后续的脚本?这样的话,相对去没有 @require 的不就是延后了?...

但是@require会有缓存的,对自己脚本执行没有什么影响,可以忽略不计

李恒道 发表于 2024-8-8 09:49:40

yhzc2023 发表于 2024-8-6 20:56
哥哥啊,通过 @require 这种方法注入脚本是不是会延后执行脚本的时刻?

require相当于

A代码
脚本代码

下载一般会缓存很久
执行的话现代计算机几十万行都是框架+垫层,几乎忽略不计

而且油猴也不是很保证执行时机


总体来说油猴的注入执行都是一些比较模糊的执行时
一般不会考虑精确的执行时刻
页: [1]
查看完整版本: 分享一个XMLHttpRequest网络数据包拦截分析