96SEO 2026-08-02 03:15 19
webContents 是负责渲染和控制网页的模块,是 BrowserWindow 对象的属性。
┌─────────────────────────────────────────────────────────┐
│ BrowserWindow │
│ ┌─────────────────────────────────────────────────┐ │
│ │ webContents │ │
│ │ │ │
│ │ • 加载页面 │ │
│ │ • 导航控制 │ │
│ │ • 页面操作 │ │
│ │ • 开发者工具 │ │
│ └─────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────┘
const { BrowserWindow } = require
// 通过 BrowserWindow 获取
const win = new BrowserWindow
const contents = win.webContents
// 通过 ID 获取
const { webContents } = require
const contentsById = webContents.fromId
文档导航
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
did-start-loading → 开始加载
will-frame-navigate → 任意 frame 准备导航
will-navigate → 主 frame 准备导航
will-redirect → 重定向发生时
did-redirect-navigation → 重定向完成
did-frame-navigate → 任意 frame 导航完成
did-navigate → 主 frame 导航完成
did-finish-load → 加载完成
did-stop-loading → 停止加载
dom-ready → DOM 准备就绪
did-start-loading →
did-navigate-in-page → 页面内导航完成
did-stop-loading →
| 事件 | 触发时机 | 可取消? | 适用场景 |
|---|---|---|---|
will-navigate | 主 frame 导航前 | ✅ | 阻止外部链接、校验 URL 权限 |
will-frame-navigate | 任意 frame 导航前 | ✅ | 统一安全策略、限制 iframe |
will-redirect | 重定向即将发生 | ✅ | 防止恶意跳转、记录审计 |
did‑navigate\` \` \`\\\`\\\`\\\`\` \` \`\`\` \`\`\``} |

const { BrowserWindow } = require
const win = new BrowserWindow
const { webContents } = win
// 拦截外部链接
webContents.on => {
console.log
if ) {
event.preventDefault
console.warn
// 可将被拦截的 URL 写入本地日志或上报服务器
// logBlockedUrl
}
})
// 捕获成功导航,用于统计 PV/UV
webContents.on => {
console.log
})
// 页面内 hash / pushState 跳转监控
webContents.on => {
console.log
})
| 事件名 | 说明 |
|---|---|
| 加载开始 |
加载结束 | |
did - finish - load> td> 页面已完整渲染,可进行 DOM 操作。 | |
did - fail - load> td> 加载失败,返回错误码与描述。 | |
dom - ready> td> DOM 已解析完毕,适合注入脚本。 | |
did - frame - finish - load> td> 单个 Frame 完成加载,适用于多帧页面监控。 |
webContents.on => { console.log // showSpinner } ) webContents.on => { console.log // 可以安全执行 injectScript } ) webContents.on => { console.log // hideSpinner } ) webContents.on => { console.error` ) // reportErrorToServer } )
webContents.on => { console.log console.log console.log console.log // 示例:只允许特定域名的新窗口打开,其他全部在当前页打开或直接阻断 if ) { // 拒绝新窗口。让其在原窗口中打开或直接忽略 newWin.close return { action : 'deny' } } // 为新窗口自定义尺寸、标题等属性 return { action : 'allow',overrideBrowserWindowOptions : { width : 800,height :600,title : details.frameName || '子窗口' } } } )
webContents.on => { console.log // 示例:限制最小宽高,防止被拖得太小导致 UI 消失 if { event.preventDefault // 阻止本次更新 win.setBounds console.warn } } )
// 渲染进程崩溃或被程序回收 webContents.on => { console.error switch { case 'crashed': // 可尝试重新加载错误页或主入口页 win.loadFile break;case 'oom': dialog.showMessageBoxSync({ type :'warning'。message :'内存不足,请关闭其他窗口后重试。' }) break,default: win.reload } } ) // 页面卡死检测 webContents.on => { console.warn const choice = dialog.showMessageBoxSync({ type :'question'。buttons:,message:'页面已无响应,是否立即刷新?' }) if webContents.reload } ) webContents.on =>{ console.log } )
webContents.on( 'will-prevent-unload'。async event =>{ const result = await dialog.showMessageBox({ type :'question',buttons:,defaultId:1,message:'当前页面有未保存的数据,确定离开吗?' }) if { event.preventDefault // 留在当前页面 } } )
const { webContents } = require // 所有已创建的 WebContents 实例数组 const all = webContents.getAllWebContents console.log // 当前聚焦的 WebContent const focused = web_contents.getFocusedWebContents if{ console.log) }
const wcById = web_contents.fromId // 根据内部 id 获取 const wcByFrame = web_contents.fromFrame // Frame -> WebContent const wcByDevTools = web_contents.fromDevToolsTargetId // DevTools 调试目标获取
await web_contents.loadURL await web_contents.loadFile await web_contents.loadURL('https://example.com'。{ httpReferrer:'https://google.com',userAgent:'MyApp/1.0',extraHeaders:'X-Custom:123' })
if) web_contents.goBack if) web_contents.goForward // 跳转到历史记录中的相对位置,例如后退两步: web_contents.goToOffset // 跳转到具体索引: web_contents.goToIndex // 获取完整历史信息: const historyInfo = web_contents.getNavigationHistory console.log
web_contents.print) await web_contents.savePage web_contents.setZoomFactor // 放大至125% console.log) web_contents.focus // 主动聚焦对应窗口/标签页 // 打开/关闭开发者工具并查询状态: web_contents.openDevTools console.log)
await web_contents.executeJavaScript(` document.title = ' '+document.title;window.__APP_VERSION__='v1.0';`).n=>console.log) // 主进程向渲染进程发送自定义消息: web_contents.send // 渲染进程接收示例 /* const { ipcRenderer } = require ipcRenderer.on=>{ console.info;}) */
class PageLoader{ constructor{ this.wc=wc;this.init,} init{ this.wc.on=>{ this.showLoading;}) this.wc.on=>{ this.injectDebug;}) this.wc.on=>{ this.showLoading;}) this.wc.on=>{ this.showError;}) this.wc.on=>{ if this.showCrash;}) } showLoading{ /* UI 控制 */ } showError{ /* 错误弹窗 */ } showCrash{ /* 崩溃页 */ } async injectDebug{ await this.wc.executeJavaScript;`),} } new PageLoader;
class NavigationGuard{ constructor{ this.wc=wc;this.whitelist=whitelist;this.setup,} setup{ this.wc.on=>{ const host=new URL.hostname;if){ e.preventDefault;console.warn;// 写入审计日志,} });this.wc.on=>{ /* 同上 */ });} } new NavigationGuard;
class HotReload{ constructor{ this.wc=wc;this.enabled=false;话说回来,this.handleFinish=this.handleFinish.bind; 其实,} enable{ ifreturn; this.enabled=true;this.wc.on,console.info;} disable{ ifreturn;this.enabled=false;this.wc.removeListener;console.info;} handleFinish{ if{ setTimeout=>this.wc.reload,100); // 防抖避免循环 reload } } } new HotReload.enable;
async function injectScripts{ try{ await wc.whenReady;// 确保已初始化完毕 const result=await wc.executeJavaScript(` =>{ const style=document.createElement;style.textContent=".debug{border:1px solid red}";document.head.appendChild;return true,});`),if console.info;}catch{ console.error;} } injectScripts;
win.webContents.setWindowOpenHandler=>{ if){ return {action:"allow"。overrideBrowserWindowOptions:{ width的观点是,1024,height:768,title:frameName||"子窗口" }};} // 拒绝非信任域名的新窗口,在当前页打开或直接忽略。return {action:"deny"};}),
再看使用者痛点一,**外链导致信息泄露** — 使用者经常发现点击邮件或聊天中的链接后被 Electron 应用自动打开并执行潜在恶意脚本。按理说,
NavigationGuard只允许白名单域名;开启 **Content‑Security‑Policy 并在 BrowserWindow.webPreferences 中禁用 nodeIntegration。
javascript
win.webPreferences={
nodeIntegration:false。contextIsolation:true,sandbox:true,enableRemoteModule:false,preload:path.join
};
javascript
// 主进程统一拦截所有 navigation 行为
win.webContents.setPermissionRequestHandler=>{
const allowed=;callback),});
从使用者痛点二来看,**渲染进程崩溃导致整个应用卡死** — 使用者报告“打开某个网页后整个桌面应用无响应”。
使用者痛点三的观点是,**开发阶段频繁手动刷新 & 注入脚本** — 开发者每次改动都要手动 reload 并重新注入调试脚本。
dom-ready 时自动注入调试工具栏。
fs.watch 检测源码目录变化;不过,触发 win.webcontents.reload;怎么说呢,随后调用 injectScripts 注入最新调试脚本。
devtoolsExtensionPath: 指定自研 DevTools 插件方法,实现一次性注入全部调试功能。
fs.watch。{recursive:true},=>hotReloader.enable);
以上方案从根源定位了三个最常见的 “渲染/安全” 痛点,并给出了 实战代码 + 推荐配置。把这些片段直接复制到你的 Electron 项目,即可明显提高页面渲染可靠性与安全防护水平。
文档基于 Electron v28+ WebConte nts API 编写,如需兼容旧版请参考官方迁移教程。
| ⚡️ 导航相关事件速查表 ⚡️️️︎︎︎︎︎︎︎︎︎︎︎︎︎︎⠀⠀⠀⠀ ⠀⠀⠀⠀ ⠀⠀⠀ ⠀⠀ ⠀⠀⠀⠀⟿⟿⟿⟿⟿⟿⟿⟿⟿⟿⬅⬅⬅⬅⬅⬅⬅⬅⬅☞☞☞☞☞☞✈✈✈✈✈✈✈✈✈✈ ✏️✨🌠🌤🚀🚁🛰📱📊📊⚙⚙⚙⚙⚙⚙⚙ ⚽🏓🏸🥊🥎🏹🎱 🏎 🚓 🚕 🚁 🛸 🛰 📺 👾 🙇 🙍 🙍🏻 🙍🏼 🙍🏽🙍🏾🙍🏿 😵 😴 😎 🤖 👽 👾🤯🤬🤓🐱🐶🐭🐰🐸🦉🕷🦂💣🔥💥🌊💨🌪 🌜 🌝 🌚 🌞 🌑 🌒 🌓🌔🌕 |
|---|
作为专业的SEO优化服务提供商,我们致力于通过科学、系统的搜索引擎优化策略,帮助企业在百度、Google等搜索引擎中获得更高的排名和流量。我们的服务涵盖网站结构优化、内容优化、技术SEO和链接建设等多个维度。
| 服务项目 | 基础套餐 | 标准套餐 | 高级定制 |
|---|---|---|---|
| 关键词优化数量 | 10-20个核心词 | 30-50个核心词+长尾词 | 80-150个全方位覆盖 |
| 内容优化 | 基础页面优化 | 全站内容优化+每月5篇原创 | 个性化内容策略+每月15篇原创 |
| 技术SEO | 基本技术检查 | 全面技术优化+移动适配 | 深度技术重构+性能优化 |
| 外链建设 | 每月5-10条 | 每月20-30条高质量外链 | 每月50+条多渠道外链 |
| 数据报告 | 月度基础报告 | 双周详细报告+分析 | 每周深度报告+策略调整 |
| 效果保障 | 3-6个月见效 | 2-4个月见效 | 1-3个月快速见效 |
我们的SEO优化服务遵循科学严谨的流程,确保每一步都基于数据分析和行业最佳实践:
全面检测网站技术问题、内容质量、竞争对手情况,制定个性化优化方案。
基于用户搜索意图和商业目标,制定全面的关键词矩阵和布局策略。
解决网站技术问题,优化网站结构,提升页面速度和移动端体验。
创作高质量原创内容,优化现有页面,建立内容更新机制。
获取高质量外部链接,建立品牌在线影响力,提升网站权威度。
持续监控排名、流量和转化数据,根据效果调整优化策略。
基于我们服务的客户数据统计,平均优化效果如下:
我们坚信,真正的SEO优化不仅仅是追求排名,而是通过提供优质内容、优化用户体验、建立网站权威,最终实现可持续的业务增长。我们的目标是与客户建立长期合作关系,共同成长。
Demand feedback