Chrome扩展开发:如何禁用文件选择窗口及精准拦截文件上传请求?
针对你的两个核心需求,以下是具体的实现方案:
一、完全禁用文件选择窗口的方法
Chrome扩展可以通过Content Script注入代码,从源头覆盖所有可能触发文件选择窗口的途径:
拦截原生文件选择API
现代网站可能使用window.showOpenFilePicker()这个原生API触发文件选择,直接覆盖该方法使其失效:// 在Content Script中注入这段代码 window.showOpenFilePicker = () => Promise.reject(new Error("文件选择已禁用"));全方位阻断file input相关操作
不仅要处理已存在的<input type="file">,还要拦截动态创建的元素,以及阻止关联按钮的点击事件:// 监听DOM变化,自动禁用/移除新创建的file input const observer = new MutationObserver(mutations => { mutations.forEach(mutation => { mutation.addedNodes.forEach(node => { if (node.tagName === 'INPUT' && node.type === 'file') { node.disabled = true; node.remove(); } }); }); }); observer.observe(document.body, { childList: true, subtree: true }); // 在捕获阶段拦截所有点击,阻止触发file input的元素 document.addEventListener('click', e => { const target = e.target; // 检查当前元素是否关联了file input const linkedFileInput = target.querySelector('input[type=file]') || document.querySelector(`input[type=file][id="${target.getAttribute('for')}"]`); if (linkedFileInput) { e.preventDefault(); e.stopPropagation(); } }, true);阻止动态创建file input
覆盖document.createElement,让页面无法创建新的file input元素:const originalCreate = document.createElement; document.createElement = function(tagName) { const elem = originalCreate.call(this, tagName); if (tagName.toLowerCase() === 'input' && elem.type === 'file') { elem.disabled = true; // 也可以直接返回空节点,彻底阻止创建 return document.createTextNode(''); } return elem; };
二、精准识别文件上传请求的方法
全局修改Content-Type的方案过于粗暴,推荐以下几种精准拦截的方式:
匹配
multipart/form-data类型的请求
文件上传请求几乎都会使用multipart/form-data作为Content-Type,用declarativeNetRequest规则只针对这类请求操作:// manifest.json中声明规则资源 "declarative_net_request": { "rule_resources": [ { "id": "upload_block_rules", "enabled": true, "path": "rules.json" } ] }// rules.json 中的具体规则 [ { "id": 1, "priority": 1, "action": { "type": "modifyHeaders", "requestHeaders": [ { "header": "Content-Type", "operation": "set", "value": "application/json; charset=utf-8" } ] }, "condition": { "urlFilter": "*", "resourceTypes": ["xmlhttprequest", "fetch"], "requestHeaders": [ { "header": "Content-Type", "operator": "contains", "value": "multipart/form-data" } ] } } ]用
webRequestAPI检查请求体
如果需要判断请求中是否真的包含文件,可以用webRequest.onBeforeRequest读取请求体,针对性拦截:// background.js中实现 chrome.webRequest.onBeforeRequest.addListener( details => { if (details.method === 'POST' && details.requestBody) { // 检查请求体是否包含文件数据 const hasFile = details.requestBody.formData && Object.values(details.requestBody.formData).some(group => group.some(item => item.file) ); if (hasFile) { return { cancel: true }; // 直接拦截请求 } } }, { urls: ["<all_urls>"] }, ["requestBody"] // 需要在manifest中申请该权限 );注意:这个方法需要
webRequest和webRequestBlocking权限,且读取请求体可能有性能损耗,适合对特定网站做精细控制。匹配特定上传接口路径
如果目标网站的上传接口有固定路径(比如/api/upload、/file/upload),直接在规则中匹配这些URL,是最精准的拦截方式。
内容的提问来源于stack exchange,提问作者Yakov Borukhov

