油猴脚本高级应用:拦截与修改网页Fetch请求实战指南

油猴脚本高级应用:拦截与修改网页Fetch请求实战指南

简介:

本文介绍了几个使用油猴(Tampermonkey)脚本拦截和修改网页 fetch 请求的案例。这些脚本可以在浏览器扩展油猴中运行,用于开发者调试网络请求或自定义页面行为。

核心内容:

  1. fetch 拦截案例2:通过覆盖原生 fetch 函数,拦截请求并修改响应的 json 方法,添加自定义属性 hook。但此方法可能会漏掉一些请求。
  2. fetch 拦截案例1:同样覆盖原生 fetch,但通过检查请求的URL,只拦截特定域名(如 bilivideo.com)的请求,其他请求正常放行,避免误拦截。
  3. 国外大神脚本:一个示例脚本框架,展示了油猴脚本的基本结构和元数据,包括运行时机、脚本名称、描述、作者信息等。此脚本实际功能尚未实现,但提供了一个扩展和自定义的起点。

使用场景:

  • 网络调试:开发者可以在开发过程中使用这些脚本来拦截和分析网络请求,方便定位问题。
  • 页面自定义:用户可以通过修改响应数据,实现对网页内容的个性化定制。
  • 学习参考:油猴脚本的示例为学习如何使用油猴扩展和JavaScript进行浏览器自动化提供了参考。

注意事项:

  • 脚本运行时机(@run-at)设置为 document-start,确保尽早覆盖原生函数。
  • 使用 @grant unsafeWindow 声明,授予脚本访问或修改全局窗口对象的权限。
  • 脚本可能需要根据实际网页结构和需求进行调整和完善。

fetch 拦截请求案例2(会漏掉一些请求)

// @run-at    document-start
// @grant     unsafeWindow
(function () {    
    let oldfetch = fetch;
    function fuckfetch() {
        return new Promise((resolve, reject) => {
            //console.log("arguments",arguments)
            oldfetch.apply(this, arguments).then(response => {
                const oldJson = response.json;
                console.log(response.url)
                response.json = function() {
                    return new Promise((resolve, reject) => {
                        oldJson.apply(this, arguments).then(result => {
                            result.hook = 'success';
                            resolve(result);
                        });
                    });
                };
                resolve(response);
            });
        });
    }
    unsafeWindow.fetch = fuckfetch;
    
})();

fetch 拦截请求案例1(会漏掉一些请求)

把运行时间设置为document-start,确保能拦截到较早发出的请求。

这里我通过url判断是否为获取b站直播流的请求,如果不是则不拦截,避免误伤。

// @run-at    document-start
// @grant     unsafeWindow
(function () {    
    const originFetch = fetch;
    unsafeWindow.fetch = (...arg) => {
        console.log('fetch arg', ...arg);
        if (arg[0].indexOf('bilivideo.com') > -1) {
            //console.log('拦截直播流')
            return new Promise(() => {
                throw new Error();
            });
        } else {
            //console.log('通过')
            return originFetch(...arg);
        }
    }
})();

国外大神的脚本(最能拦截所有)

来自国外大神的脚本,直接执行即可

// ==UserScript==
// @run-at    document-start
// @name         CSDN-创作中心
// @namespace    http://tampermonkey.net/
// @version      0.1
// @description  try to take over the world!
// @author       wusp
// @match        https://mp.csdn.net/*
// @exclude		   这个和 iclude 配合使用,排除匹配到的网址,优先于 include
// @require      http://code.jquery.com/jquery-1.11.0.min.js
// @grant        unsafeWindow
// ==/UserScript==

(function () {
    'use strict';

    $(() => { 
    	function addXMLRequestCallback(callback){
            // 是一个劫持的函数
            var oldSend, i;
            if( XMLHttpRequest.callbacks ) {
                //   判断XMLHttpRequest对象下是否存在回调列表,存在就push一个回调的函数
                // we've already overridden send() so just add the callback
                XMLHttpRequest.callbacks.push( callback );
            } else {
                // create a callback queue
                XMLHttpRequest.callbacks = [callback];
                // 如果不存在则在xmlhttprequest函数下创建一个回调列表
                // store the native send()
                oldSend = XMLHttpRequest.prototype.send;
                // 获取旧xml的send函数,并对其进行劫持
                // override the native send()
                XMLHttpRequest.prototype.send = function(){
                    // process the callback queue
                    // the xhr instance is passed into each callback but seems pretty useless
                    // you can't tell what its destination is or call abort() without an error
                    // so only really good for logging that a request has happened
                    // I could be wrong, I hope so...
                    // EDIT: I suppose you could override the onreadystatechange handler though
                    for( i = 0; i < XMLHttpRequest.callbacks.length; i++ ) {
                        XMLHttpRequest.callbacks[i]( this );
                    }
                    // 循环回调xml内的回调函数
                    // call the native send()
                    oldSend.apply(this, arguments);
                //    由于我们获取了send函数的引用,并且复写了send函数,这样我们在调用原send的函数的时候,需要对其传入引用,而arguments是传入的参数
                }
            }
        }
        
        // e.g.
        addXMLRequestCallback( function( xhr ) {
                // 调用劫持函数,填入一个function的回调函数
                // 回调函数监听了对xhr调用了监听load状态,并且在触发的时候再次调用一个function,进行一些数据的劫持以及修改
                xhr.addEventListener("load", function(){
                if ( xhr.readyState == 4 && xhr.status == 200 ) {
                    console.log( xhr.responseURL );
                }
            });
        
        });
    
    })
})();

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

桃宝护卫队

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

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

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

打赏作者

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

抵扣说明:

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

余额充值