Greasy Fork is available in English.
支持GoFile游客批量下载文件
当前为
// ==UserScript==
// @name GoFile 批量下载(免登录)
// @namespace http://tampermonkey.net/
// @version 1.8
// @description 支持GoFile游客批量下载文件
// @author 杰哥不要啊(❁´ω`❁)*✲゚*
// @match https://gofile.io/*
// @grant none
// @run-at document-start
// @license MIT
// ==/UserScript==
(function () {
'use strict';
let allLinks = [];
function extractLinks(obj, links = []) {
if (obj && typeof obj === 'object') {
if (typeof obj.link === 'string') {
links.push(obj.link);
}
for (const key in obj) {
if (obj.hasOwnProperty(key)) {
extractLinks(obj[key], links);
}
}
}
return links;
}
const origFetch = window.fetch;
window.fetch = async function (...args) {
const response = await origFetch.apply(this, args);
try {
const u = new URL(response.url);
if (u.hostname.endsWith('.gofile.io') && u.pathname.startsWith('/contents/')) {
const clone = response.clone();
try {
const jsonData = await clone.json();
allLinks = [...new Set(extractLinks(jsonData))].filter(url => url.trim());
console.log('✅ 解析出的 GoFile links:', allLinks);
addBatchDownloadButton();
} catch (e) {
console.error('❌ JSON 解析失败:', e);
}
}
} catch (e) { /* ignore */ }
return response;
};
function addBatchDownloadButton() {
if (document.getElementById('gofile-batch-btn')) return;
const btn = document.createElement('button');
btn.id = 'gofile-batch-btn';
btn.textContent = '🔽 批量下载';
Object.assign(btn.style, {
position: 'fixed',
top: '15px',
right: '15px',
zIndex: '2147483647',
padding: '8px 12px',
background: '#FF9800',
color: 'white',
border: 'none',
borderRadius: '4px',
cursor: 'pointer',
fontSize: '13px',
fontWeight: 'bold',
boxShadow: '0 2px 6px rgba(0,0,0,0.2)'
});
btn.onclick = openDownloadModal;
if (document.body) {
document.body.appendChild(btn);
} else {
const observer = new MutationObserver(() => {
if (document.body) {
document.body.appendChild(btn);
observer.disconnect();
}
});
observer.observe(document.documentElement, { childList: true, subtree: true });
}
}
function openDownloadModal() {
if (!allLinks || allLinks.length === 0) {
alert('⚠️ 未提取到任何 link,请等待页面加载完成。');
return;
}
const overlay = document.createElement('div');
Object.assign(overlay.style, {
position: 'fixed',
top: '0',
left: '0',
width: '100%',
height: '100%',
backgroundColor: 'rgba(0,0,0,0.6)',
zIndex: '2147483646',
display: 'flex',
justifyContent: 'center',
alignItems: 'center'
});
const modal = document.createElement('div');
Object.assign(modal.style, {
background: 'white',
width: '90%',
maxWidth: '500px',
maxHeight: '80vh',
overflow: 'auto',
borderRadius: '10px',
padding: '20px',
boxShadow: '0 5px 25px rgba(0,0,0,0.3)',
fontFamily: '-apple-system, BlinkMacSystemFont, sans-serif',
color: '#000'
});
// 👇 新增:下载位置提示
const tip = document.createElement('div');
tip.innerHTML = `
💡 <strong>想自选保存位置?</strong><br>
<em>①修改浏览器默认下载位置</em><br>
②请在浏览器设置中开启:<em>“下载前询问保存位置”</em>(Chrome/Firefox 均支持)
`;
tip.style.fontSize = '12px';
tip.style.color = '#555';
tip.style.marginBottom = '12px';
tip.style.padding = '8px';
tip.style.backgroundColor = '#fff8e1';
tip.style.borderRadius = '4px';
tip.style.lineHeight = '1.4';
modal.appendChild(tip);
const title = document.createElement('h3');
title.textContent = `🔽 批量下载 (${allLinks.length} 个文件)`;
title.style.marginTop = '0';
title.style.color = '#333';
modal.appendChild(title);
const listContainer = document.createElement('div');
Object.assign(listContainer.style, {
maxHeight: '400px',
overflowY: 'auto',
margin: '15px 0',
border: '1px solid #ddd',
borderRadius: '6px',
padding: '10px',
backgroundColor: '#f9f9f9'
});
modal.appendChild(listContainer);
allLinks.forEach(link => {
const row = document.createElement('div');
row.style.display = 'flex';
row.style.alignItems = 'center';
row.style.padding = '8px 0';
const checkbox = document.createElement('input');
checkbox.type = 'checkbox';
checkbox.checked = true;
checkbox.dataset.url = link;
checkbox.style.marginRight = '10px';
checkbox.style.flexShrink = '0';
const filename = link.split('/').pop() || 'unknown_file';
const span = document.createElement('span');
span.style.fontSize = '14px';
span.style.color = '#000';
span.title = link; // 悬停看完整链接
span.textContent = filename;
row.appendChild(checkbox);
row.appendChild(span);
listContainer.appendChild(row);
});
const buttonBar = document.createElement('div');
buttonBar.style.display = 'flex';
buttonBar.style.gap = '10px';
buttonBar.style.marginTop = '15px';
buttonBar.style.flexWrap = 'wrap';
const createButton = (text, bg, onClick) => {
const btn = document.createElement('button');
btn.textContent = text;
Object.assign(btn.style, {
padding: '6px 12px',
background: bg,
color: 'white',
border: 'none',
borderRadius: '4px',
cursor: 'pointer',
whiteSpace: 'nowrap'
});
btn.onclick = onClick;
return btn;
};
buttonBar.appendChild(createButton('全选', '#2196F3', () => {
modal.querySelectorAll('input[type="checkbox"]').forEach(cb => cb.checked = true);
}));
buttonBar.appendChild(createButton('取消全选', '#9E9E9E', () => {
modal.querySelectorAll('input[type="checkbox"]').forEach(cb => cb.checked = false);
}));
buttonBar.appendChild(createButton('开始下载', '#4CAF50', () => {
const selected = Array.from(modal.querySelectorAll('input[type="checkbox"]:checked'))
.map(cb => cb.dataset.url);
if (selected.length === 0) {
alert('请选择至少一个文件');
return;
}
overlay.remove();
// 使用 iframe 方式触发下载(更可靠)
selected.forEach((url, i) => {
setTimeout(() => {
const iframe = document.createElement('iframe');
iframe.style.display = 'none';
iframe.src = url;
document.body.appendChild(iframe);
// 可选:稍后移除 iframe
setTimeout(() => {
if (iframe.parentNode) iframe.parentNode.removeChild(iframe);
}, 1000);
}, i * 800); // 间隔稍长,避免浏览器拦截
});
console.log(`🚀 开始下载 ${selected.length} 个文件`);
}));
buttonBar.appendChild(createButton('关闭', '#f44336', () => {
overlay.remove();
}));
modal.appendChild(buttonBar);
try {
overlay.appendChild(modal);
document.body.appendChild(overlay);
} catch (e) {
console.error('❌ 弹窗创建失败:', e);
if (overlay.parentNode) overlay.parentNode.removeChild(overlay);
alert('❌ 弹窗初始化失败,请刷新重试。');
}
}
})();