访问.exe结尾URL时如何先检查二进制文件再决定是否下载
解决方案:在下载.exe文件前查看内容
核心问题原因
浏览器针对.exe这类二进制文件,不会创建可注入内容脚本的页面环境,所以普通的内容脚本根本没机会执行。得用浏览器扩展的后台API来拦截请求或干预下载流程。
方法一:用webRequest API拦截请求(推荐)
这个API能在请求发送/响应阶段直接介入,完全可以在下载开始前拿到文件内容。步骤如下:
- 在扩展的
manifest.json里声明必要权限:
{ "manifest_version": 3, "name": "EXE Preview", "version": "1.0", "permissions": ["webRequest", "webRequestBlocking", "storage"], "host_permissions": ["<all_urls>"], "background": { "service_worker": "background.js" } }
- 在
background.js里监听请求,拦截.exe文件:
chrome.webRequest.onHeadersReceived.addListener( (details) => { // 检查URL是否以.exe结尾,同时确认响应是二进制类型 if (details.url.endsWith('.exe') && details.responseHeaders.some(h => h.name.toLowerCase() === 'content-type' && h.value.startsWith('application/octet-stream'))) { // 取消原下载请求 return { cancel: true }; } }, { urls: ["<all_urls>"], types: ["main_frame", "sub_frame"] }, ["responseHeaders", "blocking"] ); // 取消后,手动发起请求获取内容,处理后再决定是否下载 chrome.webRequest.onCompleted.addListener( async (details) => { if (details.url.endsWith('.exe')) { try { const response = await fetch(details.url); const blob = await response.blob(); // 这里写你的内容处理逻辑,比如读取二进制头、提取信息等 console.log('获取到exe文件Blob:', blob); // 处理完后如果要下载,创建下载链接 const url = URL.createObjectURL(blob); const a = document.createElement('a'); a.href = url; a.download = details.url.split('/').pop(); a.click(); URL.revokeObjectURL(url); } catch (err) { console.error('获取文件内容失败:', err); } } }, { urls: ["<all_urls>"], types: ["main_frame", "sub_frame"] } );
注意:Manifest V3里要用service worker作为后台脚本,V2则用background page,代码逻辑基本一致。
方法二:用downloads API干预下载流程
如果不想拦截原始请求,可以监听下载创建事件,暂停后获取内容:
- 同样在
manifest.json里添加downloads权限:
"permissions": ["downloads", "downloads.open"]
- 后台脚本里监听下载:
chrome.downloads.onCreated.addListener(async (downloadItem) => { if (downloadItem.url.endsWith('.exe')) { // 暂停下载 await chrome.downloads.pause(downloadItem.id); // 发起请求获取文件内容 const response = await fetch(downloadItem.url); const blob = await response.blob(); // 处理内容逻辑... // 处理完后,要么恢复下载,要么取消并手动下载处理后的文件 await chrome.downloads.resume(downloadItem.id); // 或者取消原下载,自己创建新下载 // await chrome.downloads.cancel(downloadItem.id); // 然后执行手动下载逻辑 } });
这个方法的缺点是浏览器已经开始创建下载项了,但依然能在文件完成下载前拿到内容。
注意事项
- 跨域问题:如果目标网站有CORS限制,fetch请求可能失败,这时候需要在扩展的
manifest.json里添加"host_permissions"覆盖对应域名,或者在webRequest里修改响应头添加CORS允许(不过可能违反网站规则)。 - 性能:大体积的exe文件要注意内存占用,处理时尽量用流式读取,避免一次性加载整个文件到内存。
内容的提问来源于stack exchange,提问作者leo bertrand
相关产品推荐
相关产品推荐

