如何不重复请求URL获取外部<script>内容及访问Chrome DevTools缓存脚本
问题背景
现有页面包含如下脚本引用:
<html> <head> ... <script type="text/javascript" src="http://someserver/jquery-2.1.0.min.js"></script> <script type="text/javascript" src="http://someserver/getJS?key=123456" ></script> ... </head> ... </html>其中
getJS接口返回的内容为:$(document).ready(function() { ... }注意:
key是页面加载时动态生成的会话密钥,每个key对应的getJS接口仅可访问一次,再次请求会返回NULL,但Chrome开发者工具的Resources/Application面板中已经缓存了该脚本的内容。
问题解答
1. 用GreaseMonkey脚本/代码片段获取外部<script>内容(不重复请求)
核心思路是复用浏览器已加载/缓存的资源,绝对不能重新发起请求浪费一次性密钥。这里给你两种靠谱的实现方式:
方式一:利用fetch强制读取缓存
这种方法兼容性好,GreaseMonkey脚本直接就能用,原理是告诉浏览器必须用缓存里的内容,不发起新请求:
// GreaseMonkey脚本示例 // ==UserScript== // @name Grab Cached External Script // @match *://你的目标域名/* // @grant none // ==/UserScript== async function getCachedScriptContent(scriptUrl) { try { // 强制使用缓存,不会触发新请求 const response = await fetch(scriptUrl, { cache: 'force-cache' }); // 检查是否从缓存获取(可选,验证用) if (response.headers.get('x-cache') === 'HIT') { console.log('从缓存读取脚本'); } return await response.text(); } catch (err) { console.error('读取脚本失败:', err); return null; } } // 调用示例:找到目标脚本并获取内容 const targetScript = document.querySelector('script[src*="getJS?key="]'); if (targetScript) { getCachedScriptContent(targetScript.src).then(content => { if (content) { console.log('拿到脚本内容啦:', content); // 这里可以把内容存到变量或者做其他处理 } }); }
方式二:全局函数源码读取(仅限脚本暴露全局函数的情况)
如果getJS里的函数是绑定在全局对象(比如window)上的,那你可以直接通过toString()拿到它的源码,完全不需要请求:
// 假设脚本里的函数是window.myInitFunc if (window.myInitFunc) { const scriptContent = window.myInitFunc.toString(); console.log('函数源码:', scriptContent); }
不过这个方法局限性大,只适用于脚本里有全局暴露的函数的场景,匿名函数就不行了。
2. Chrome DevTools中访问Resources/Application面板的资源
Chrome DevTools提供了好几种方式直接读取这些缓存的脚本和资源,给你列几个实用的:
方法一:控制台快速读取选中的脚本
- 打开DevTools,切换到Sources面板(或者旧版的Resources),找到你要的脚本并点击选中它
- 切换到Console面板,输入
$0,这代表你当前选中的元素/资源 - 输入
$0.text就能直接拿到脚本的内容字符串!
方法二:用调试协议API批量获取所有脚本
如果要批量处理或者自动化读取,可以用Chrome的调试协议API,写个代码片段运行:
// DevTools代码片段示例,需要在Sources > Snippets里新建运行 async function fetchAllLoadedScripts() { // 附加调试器(这里的target ID可以用自己的,或者用第一个可用的) const [target] = await chrome.debugger.getTargets(); await chrome.debugger.attach(target.id, '1.3'); // 获取所有已加载的脚本 const { result: { scripts } } = await chrome.debugger.sendCommand(target.id, 'Runtime.getScripts'); // 筛选目标脚本并获取内容 for (const script of scripts) { if (script.url.includes('getJS?key=')) { const { result: { scriptSource } } = await chrome.debugger.sendCommand(target.id, 'Runtime.getScriptSource', { scriptId: script.scriptId }); console.log('目标脚本内容:', scriptSource); } } // detach调试器 await chrome.debugger.detach(target.id); } fetchAllLoadedScripts();
注意:运行这个需要先开启Chrome的开发者模式,在chrome://extensions/里开启,并且允许DevTools调试权限。
方法三:直接读取Cache Storage缓存
如果脚本存在Application面板的Cache Storage里,用caches API直接读取:
// 在DevTools控制台运行 async function getCachedResourceFromStorage() { const cacheNames = await caches.keys(); for (const name of cacheNames) { const cache = await caches.open(name); const response = await cache.match('http://someserver/getJS?key=123456'); if (response) { const content = await response.text(); console.log('缓存里的脚本内容:', content); break; } } } getCachedResourceFromStorage();
这个方法完全不会发起网络请求,直接从本地缓存拿内容,完美适配你的一次性密钥场景。
内容的提问来源于stack exchange,提问作者fred
相关产品推荐
相关产品推荐

