无需登录 数据私有 本地保存

浏览器扩展样板代码生成器 - 定制 manifest 与脚本

35
0
0
0
扩展配置
基本信息
权限配置
MV3中独立为host_permissions,MV2中合并到permissions
Background 脚本
MV3仅支持Service Worker
Content 脚本
常用: <all_urls> | https://*/* | http://*/*
Popup 弹窗
Options 设置页面
代码预览
常见问题与知识点
Manifest V2 与 V3 的区别?

V3 引入 Service Worker 替代后台页面,使用action替代browser_action,主机权限独立为host_permissions,并限制远程代码执行。V2 将于 2025 年逐步淘汰,建议新项目使用 V3。

Content Script 能做什么?

Content Script 运行在网页上下文中,可以读取和修改 DOM,但运行在隔离的 JS 环境中。通过 chrome.runtime.sendMessage 与 Background 通信,实现数据交换。

如何调试浏览器扩展?

Chrome 访问 chrome://extensions/,开启开发者模式,点击"加载已解压的扩展"。每个组件都有独立的开发者工具:Background 的 Service Worker、Popup 右键检查、Content Script 在页面控制台中查看。

权限声明有什么注意事项?

Chrome Web Store 审核要求扩展只申请必要权限。activeTab 权限仅在用户点击扩展时激活,比 tabs 权限更受推荐。主机权限应尽量使用具体域名,避免 <all_urls>

Service Worker 的生命周期?

MV3 的 Service Worker 在需要时启动,空闲约30秒后自动终止。不能依赖全局变量持久化,应使用 chrome.storage 保存状态。使用 chrome.alarms 可以定时唤醒 Worker。

如何发布扩展到 Chrome Web Store?

Chrome 开发者控制台 注册开发者账号(需支付一次性注册费),上传 ZIP 包,填写描述和截图,提交审核。Edge 和 Firefox 也有各自的商店。

\n\n'; return html; } function generateDefaultPopupJs() { var code = '// Popup 脚本\n'; code += 'document.addEventListener(\'DOMContentLoaded\', () => {\n'; code += ' const btn = document.getElementById(\'main-btn\');\n'; code += ' const result = document.getElementById(\'result\');\n\n'; code += ' btn.addEventListener(\'click\', async () => {\n'; code += ' // 查询当前活动标签页\n'; code += ' const [tab] = await chrome.tabs.query({ active: true, currentWindow: true });\n'; code += ' // 向content script发送消息\n'; code += ' chrome.tabs.sendMessage(tab.id, { action: \'fromPopup\' }, (resp) => {\n'; code += ' if (chrome.runtime.lastError) {\n'; code += ' result.textContent = \'请刷新页面后重试\'; code += ' return;\n'; code += ' }\n'; code += ' result.textContent = \'操作成功: \' + JSON.stringify(resp);\n'; code += ' });\n'; code += ' });\n'; code += '});\n'; return code; } function generateDefaultOptions(name) { var html = '\n\n\n'; html += ' \n'; html += ' ' + name + ' - 设置\n'; html += ' \n\n\n'; html += '

' + name + ' 设置

\n'; html += '
\n'; html += ' \n'; html += ' \n'; html += '
\n'; html += ' \n'; html += '
\n'; html += ' \n\n'; return html; } function applyPreset(preset) { // 重置 $('input[name="manifest-version"][value="3"]').prop('checked', true).trigger('change'); $('#ext-name').val('我的扩展'); $('#ext-version').val('1.0.0'); $('#ext-desc').val(''); $('#ext-author').val(''); $('#custom-permissions').val(''); $('#host-permissions').val(''); $('#bg-code').val(''); $('#content-code').val(''); $('#content-matches').val('https://*/*'); $('#popup-html').val(''); $('#popup-js').val(''); $('#popup-title').val('扩展弹窗'); $('#enable-background').prop('checked', false).trigger('change'); $('#enable-content').prop('checked', false).trigger('change'); $('#enable-popup').prop('checked', false).trigger('change'); $('#enable-options').prop('checked', false).trigger('change'); $('#perm-chips .permission-check').removeClass('active'); if (preset === 'minimal') { $('#ext-name').val('最小扩展'); $('#ext-desc').val('一个最小化的浏览器扩展'); $('#perm-chips .permission-check[data-perm="storage"]').addClass('active'); } else if (preset === 'content') { $('#ext-name').val('网页修改器'); $('#ext-desc').val('修改网页内容的浏览器扩展'); $('#enable-content').prop('checked', true).trigger('change'); $('#content-matches').val(''); $('#perm-chips .permission-check[data-perm="storage"]').addClass('active'); $('#perm-chips .permission-check[data-perm="activeTab"]').addClass('active'); } else if (preset === 'full') { $('#ext-name').val('全功能扩展'); $('#ext-desc').val('包含完整功能的浏览器扩展'); $('#enable-background').prop('checked', true).trigger('change'); $('#enable-content').prop('checked', true).trigger('change'); $('#enable-popup').prop('checked', true).trigger('change'); $('#enable-options').prop('checked', true).trigger('change'); $('#content-matches').val('https://*/*'); $('#host-permissions').val('https://*/*'); $('#perm-chips .permission-check[data-perm="storage"]').addClass('active'); $('#perm-chips .permission-check[data-perm="tabs"]').addClass('active'); $('#perm-chips .permission-check[data-perm="activeTab"]').addClass('active'); $('#perm-chips .permission-check[data-perm="notifications"]').addClass('active'); $('#perm-chips .permission-check[data-perm="alarms"]').addClass('active'); } generateAll(); switchFile('manifest.json'); updateFileTabs(); } function copyToClipboard(text) { if (navigator.clipboard && navigator.clipboard.writeText) { navigator.clipboard.writeText(text).catch(function() { fallbackCopy(text); }); } else { fallbackCopy(text); } } function fallbackCopy(text) { var ta = document.createElement('textarea'); ta.value = text; ta.style.position = 'fixed'; ta.style.left = '-9999px'; ta.style.top = '-9999px'; document.body.appendChild(ta); ta.focus(); ta.select(); try { document.execCommand('copy'); } catch (e) {} document.body.removeChild(ta); } function downloadFile(filename, content) { var blob = new Blob([content], { type: 'application/octet-stream' }); var url = URL.createObjectURL(blob); var a = document.createElement('a'); a.href = url; a.download = filename; document.body.appendChild(a); a.click(); document.body.removeChild(a); URL.revokeObjectURL(url); } function showToast(msg) { var toast = $('
' + msg + '
'); $('body').append(toast); setTimeout(function() { toast.remove(); }, 2200); } function downloadAllAsZip() { var btn = $('#btn-download-zip'); var origText = btn.html(); btn.html('打包中...').prop('disabled', true); function doZip() { var zip = new JSZip(); var fileCount = 0; $.each(generatedFiles, function(name, content) { zip.file(name, content); fileCount++; }); // 添加README var readme = '# 浏览器扩展文件说明\n\n'; readme += '此ZIP包含浏览器扩展的所有源代码。\n\n'; readme += '## 使用方法\n'; readme += '1. 解压此ZIP文件\n'; readme += '2. 打开Chrome浏览器,访问 chrome://extensions/\n'; readme += '3. 开启右上角的"开发者模式"\n'; readme += '4. 点击"加载已解压的扩展程序"\n'; readme += '5. 选择解压后的文件夹\n\n'; readme += '## 文件列表\n'; $.each(generatedFiles, function(name) { readme += '- ' + name + '\n'; }); readme += '\n> 生成于: ' + new Date().toISOString().split('T')[0] + '\n'; zip.file('README.md', readme); zip.generateAsync({ type: 'blob' }).then(function(blob) { var url = URL.createObjectURL(blob); var a = document.createElement('a'); var zipName = ($('#ext-name').val().trim() || 'extension') + '.zip'; a.href = url; a.download = zipName.replace(/[^a-zA-Z0-9\u4e00-\u9fa5._-]/g, '_'); document.body.appendChild(a); a.click(); document.body.removeChild(a); URL.revokeObjectURL(url); btn.html(origText).prop('disabled', false); showToast('ZIP下载成功!包含 ' + fileCount + ' 个文件'); }).catch(function(err) { btn.html(origText).prop('disabled', false); showToast('打包失败,请尝试逐个下载'); console.error('ZIP生成失败:', err); }); } if (typeof JSZip !== 'undefined') { doZip(); } else { // 动态加载JSZip $.getScript('https://cdnjs.cloudflare.com/ajax/libs/jszip/3.10.1/jszip.min.js') .done(function() { doZip(); }) .fail(function() { // 尝试备用CDN $.getScript('https://unpkg.com/jszip@3.10.1/dist/jszip.min.js') .done(function() { doZip(); }) .fail(function() { btn.html(origText).prop('disabled', false); showToast('无法加载打包库,请使用逐个下载'); // 回退:逐个下载 $.each(generatedFiles, function(name, content) { setTimeout(function() { downloadFile(name, content); }, 300); }); }); }); } } // 预加载JSZip if (typeof JSZip === 'undefined') { $.getScript('https://cdnjs.cloudflare.com/ajax/libs/jszip/3.10.1/jszip.min.js').fail(function() { $.getScript('https://unpkg.com/jszip@3.10.1/dist/jszip.min.js'); }); } // 初始生成 updateBgTypeOptions('3'); generateAll(); switchFile('manifest.json'); updateFileTabs(); $('#popup-options').hide(); $('#tab-popup a').hide(); $('#tab-popup-js a').hide(); });