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

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions