如何在内存中下载文件并上传?Tampermonkey脚本实现可行性问询
无本地存储的Tampermonkey文件中转上传方案
当然可以实现啦!用浏览器JavaScript配合Tampermonkey完全能做到——全程不需要用户把文件存到本地磁盘,直接在内存里完成文件抓取到上传到你服务器的流程。下面我给你详细拆解实现逻辑、流程图和示例脚本:
为什么可行?
浏览器原生提供了Fetch/XMLHttpRequest这类网络请求API,能直接获取文件的二进制数据(以Blob或ArrayBuffer形式存在内存中),不需要写入本地磁盘。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




