写一个油猴脚本或chrome插件
点击查看全文
// ==UserScript==
// @name 合并网页代码(HTML+CSS+JS)
// @namespace http://tampermonkey.net/
// @version 1.0
// @description 自动合并当前页面的 HTML、CSS、JS 为带分隔的文本
// @author You
// @match *://*/*
// @grant GM_setClipboard
// @grant GM_xmlhttpRequest
// @connect *
// @run-at document-end
// ==/UserScript==
(function () {
'use strict';
// 等待所有资源加载(简单延迟,或可监听 load 事件)
window.addEventListener('load', () => {
setTimeout(async () => {
let output = '';
// 1. 原始 HTML(格式化)
const html = document.documentElement.outerHTML;
output += `=== HTML ===\n${html}\n\n`;
// 2. 收集所有 CSS
output += `=== CSS ===\n`;
const cssPromises = [];
// 内联样式
document.querySelectorAll('style').forEach(style => {
output += `\n/* Inline Style */\n${style.textContent}\n`;
});
// 外部样式表
document.querySelectorAll('link[rel="stylesheet"][href]').forEach(link => {
const href = new URL(link.href, location.href).href;
cssPromises.push(
fetchResource(href).then(css => {
if (css) return `\n/* External CSS: ${href} */\n${css}\n`;
return `\n/* Failed to load: ${href} */\n`;
}).catch(() => `\n/* Error loading: ${href} */\n`)
);
});
// 3. 收集所有 JS
output += `\n=== JS ===\n`;
const jsPromises = [];
// 内联脚本
document.querySelectorAll('script:not([src])').forEach(script => {
if (script.textContent.trim()) {
output += `\n/* Inline Script */\n${script.textContent}\n`;
}
});
// 外部脚本
document.querySelectorAll('script[src]').forEach(script => {
const src = new URL(script.src, location.href).href;
jsPromises.push(
fetchResource(src).then(js => {
if (js) return `\n/* External JS: ${src} */\n${js}\n`;
return `\n/* Failed to load: ${src} */\n`;
}).catch(() => `\n/* Error loading: ${src} */\n`)
);
});
// 等待所有外部资源加载完成
const cssResults = await Promise.all(cssPromises);
const jsResults = await Promise.all(jsPromises);
output += cssResults.join('');
output += jsResults.join('');
// 输出结果
console.log('合并代码完成:', output);
// 方法1:使用 GM_setClipboard(推荐,无需权限)
if (typeof GM_setClipboard === 'function') {
GM_setClipboard(output, 'text');
alert('✅ 网页代码已复制到剪贴板!\n(含 HTML + CSS + JS)');
} else {
// 方法2:尝试 navigator.clipboard(可能被拦截)
try {
await navigator.clipboard.writeText(output);
alert('✅ 代码已复制到剪贴board!');
} catch (err) {
// 方法3:弹出文本框让用户手动复制
const textarea = document.createElement('textarea');
textarea.value = output;
textarea.style.position = 'fixed';
textarea.style.left = '-9999px';
document.body.appendChild(textarea);
textarea.select();
document.execCommand('copy');
document.body.removeChild(textarea);
alert('✅ 代码已复制(备用方式)');
}
}
}, 1000); // 稍等资源加载
});
// 安全 fetch(绕过 CORS 限制,使用 GM_xmlhttpRequest)
function fetchResource(url) {
return new Promise((resolve) => {
if (typeof GM_xmlhttpRequest === 'function') {
GM_xmlhttpRequest({
method: 'GET',
url: url,
onload: (res) => resolve(res.responseText || ''),
onerror: () => resolve(''),
timeout: 5000
});
} else {
// 降级:普通 fetch(可能因 CORS 失败)
fetch(url, { mode: 'no-cors' })
.then(res => res.text().catch(() => ''))
.then(resolve)
.catch(() => resolve(''));
}
});
}
})(); 网友回复


