You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何在内存中下载文件并上传?Tampermonkey脚本实现可行性问询

无本地存储的Tampermonkey文件中转上传方案

当然可以实现啦!用浏览器JavaScript配合Tampermonkey完全能做到——全程不需要用户把文件存到本地磁盘,直接在内存里完成文件抓取到上传到你服务器的流程。下面我给你详细拆解实现逻辑、流程图和示例脚本:

为什么可行?

浏览器原生提供了Fetch/XMLHttpRequest这类网络请求API,能直接获取文件的二进制数据(以BlobArrayBuffer形式存在内存中),不需要写入本地磁盘。Tampermonkey作为用户脚本容器,能直接调用这些API,轻松完成“抓文件→存内存→传服务器”的全链路操作。

核心流程(流程图)

flowchart LR
    A[Tampermonkey脚本启动] --> B[定位目标文件URL<br/>(自动识别/用户触发)]
    B --> C[发起Fetch请求获取文件二进制数据]
    C --> D{请求成功?}
    D -->|是| E[将二进制数据转为Blob<br/>(内存暂存)]
    D -->|否| F[记录错误并终止]
    E --> G[创建FormData包装Blob<br/>(适配文件上传格式)]
    G --> H[发起POST请求到远程服务器]
    H --> I{上传成功?}
    I -->|是| J[通知用户/记录结果]
    I -->|否| K[重试或提示错误]

如果你的平台不支持Mermaid流程图,这里是文本版:

Tampermonkey脚本启动
    ↓
定位目标文件URL(自动识别页面下载链接/用户手动触发)
    ↓
发起Fetch请求获取文件二进制数据
    ↓
判断请求是否成功?
    ├─ 是 → 将二进制数据转为Blob对象(仅存在内存中)
    └─ 否 → 记录错误并终止流程
    ↓
创建FormData对象,把Blob以文件形式添加进去(符合服务器上传格式)
    ↓
发起POST请求到你的远程服务器
    ↓
判断上传是否成功?
    ├─ 是 → 提示用户成功/静默记录结果
    └─ 否 → 重试或提示用户错误信息

示例Tampermonkey脚本

下面是一个可直接参考的脚本,实现拦截页面下载按钮,自动抓取文件并上传到你的服务器:

// ==UserScript==
// @name         无本地存储文件中转上传
// @namespace    http://tampermonkey.net/
// @version      0.1
// @description  抓取网页文件直接上传到远程服务器,无需本地保存
// @author       Your Name
// @match        *://example.com/*  // 替换成你要处理的目标网站域名
// @grant        GM_xmlhttpRequest  // 跨域上传时必须启用这个权限
// ==/UserScript==

(function() {
    'use strict';

    // 监听页面点击,拦截下载按钮
    document.addEventListener('click', async (e) => {
        // 匹配带download属性的a标签,或者自定义下载链接的按钮
        const downloadElement = e.target.closest('a[download], button[data-file-url]');
        if (!downloadElement) return;

        // 阻止浏览器默认的下载行为
        e.preventDefault();
        e.stopPropagation();

        // 获取文件的真实URL
        const fileUrl = downloadElement.href || downloadElement.dataset.fileUrl;
        if (!fileUrl) {
            alert('未找到文件链接');
            return;
        }

        try {
            // 1. 抓取文件二进制数据
            const fileResponse = await fetch(fileUrl);
            if (!fileResponse.ok) throw new Error(`文件请求失败:${fileResponse.status}`);
            const fileBlob = await fileResponse.blob();

            // 2. 准备上传的FormData(和服务器接收字段对应)
            const uploadForm = new FormData();
            // 第一个参数是服务器接收的字段名,第二个是Blob,第三个是自定义文件名
            uploadForm.append('upload_file', fileBlob, 'captured_file.ext');

            // 3. 上传到你的服务器
            // 如果服务器和当前网站跨域,推荐用GM_xmlhttpRequest避开CORS限制
            const uploadResult = await fetch('https://your-server-domain.com/upload-endpoint', {
                method: 'POST',
                body: uploadForm,
                // 如果服务器需要登录凭证,可添加credentials: 'include'
            });

            if (uploadResult.ok) {
                const serverResponse = await uploadResult.json();
                alert(`文件上传成功!服务器返回:${serverResponse.message}`);
                console.log('上传详情:', serverResponse);
            } else {
                throw new Error(`上传失败:${uploadResult.status}`);
            }
        } catch (error) {
            console.error('处理出错:', error);
            alert(`操作失败:${error.message}`);
        }
    });
})();

关键注意事项

  • 跨域问题:如果你的服务器和目标文件所在网站不同域,普通fetch会触发CORS限制。此时一定要启用Tampermonkey的GM_xmlhttpRequestAPI(脚本元数据里加@grant GM_xmlhttpRequest),它不受浏览器同源策略约束。
  • 文件大小限制:内存里存大文件可能导致浏览器卡顿,建议在脚本里加个文件大小判断,比如超过100MB就提示用户跳过。
  • 服务器配置:确保你的服务器支持接收multipart/form-data格式的上传请求,并且如果跨域的话,要配置好CORS规则(允许脚本所在域名的请求)。
  • 用户体验:可以添加加载动画、成功/失败提示,让用户清楚当前操作进度,避免困惑。

内容的提问来源于stack exchange,提问作者Linux_cat

火山引擎 最新活动