Skip to content

能不能增加拦截页面所有请求的API #545

@Jw-23

Description

@Jw-23

我打算劫持 https://pan.xunlei.com/? 的fetch请求,设置了 @run-at: document-start ,发现竟然抢不过它。利用chrome.webRequest能否增加代理页面所有请求的API.

// ==UserScript==
// @name         迅雷网盘直接下载
// @namespace    org.jw23.xunlei
// @version      0.5.0
// @description  克服迅雷网盘的阻止下载操作
// @author       jw23
// @match        https://pan.xunlei.com/*
// @match        https://drive.pan.xunlei.com/* 
// @run-at       document-start
// ==/UserScript==

(function () {
    'use strict';

    const targetUrlKeyword = 'drive/v1/files'; // 目标API关键字

    function processResponse(url, responseText) {
        console.log(`[劫持成功] 正在处理来自 ${url} 的响应`);
        try {
            const data = JSON.parse(responseText);
            if (data && data.web_content_link) {
                console.log('成功解析到下载链接:', data.web_content_link);
                window.open(data.web_content_link, '_blank');
            } else {
                 console.log('响应中未找到 "web_content_link" 字段。');
            }
        } catch (e) {
            console.error('解析响应JSON失败:', e);
        }
    }

    // 定义应用劫持的函数
    function applyFetchHook() {
        // 在这里获取 window.fetch,此时它很可能已经是被网站修改过的版本
        const originalFetch = window.fetch;

        console.log("正在应用劫持... 当前的 fetch 函数是:", originalFetch);

        window.fetch = function(...args) {
            const [url] = args;
            const urlString = (typeof url === 'string') ? url : url.url;

            console.log(`[Fetch 劫持] 捕获到请求: ${urlString}`);

            // 调用我们保存的(可能是被网站修改过的)fetch,以保证网站功能正常
            const fetchPromise = Reflect.apply(originalFetch, this, args);

            if (urlString.includes(targetUrlKeyword)) {
                return fetchPromise.then(response => {
                    const clonedResponse = response.clone();
                    clonedResponse.text().then(text => {
                        processResponse(urlString, text);
                    });
                    return response;
                });
            }
            return fetchPromise;
        };

        console.log("Fetch 劫持已成功应用。");
    }

    // 关键:使用 setTimeout 将我们的劫持逻辑推迟到当前脚本执行队列末尾
    // 这使得我们有极大概率在网站自身的劫持脚本运行之后再运行,从而覆盖它
    setTimeout(applyFetchHook, 0);

    console.log("下载脚本已初始化,正在等待时机应用劫持...");

})();

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions