建网站用什么系统好,漳州北京网站建设公司,静态网站开发网站,做视频网站需要哪些手续目录
一、主进程和渲染进程
1、主进程#xff08;main#xff09;
2、渲染进程#xff08;renderer#xff09;
二、预加载脚本
三、沙盒化
为单个进程禁用沙盒
全局启用沙盒
四、环境访问权限控制#xff1a;contextIsolation和nodeIntegration
1、contextIsola…目录
一、主进程和渲染进程
1、主进程main
2、渲染进程renderer
二、预加载脚本
三、沙盒化
为单个进程禁用沙盒
全局启用沙盒
四、环境访问权限控制contextIsolation和nodeIntegration
1、contextIsolation
启用contextIsolationtrue时默认推荐做法
不启用contextIsolationfalse时
2、nodeIntegration 如果启用nodeIntegration: true不推荐
如果不启用我们应该如何借助Node.js的功能呢 Electron可以简单理解为一个桌面应用程序的“壳”内里还是遵循浏览器的行为加载网页进行渲染可以是本地、也可以是远程网页
一、主进程和渲染进程
Electron的架构其实类似现代浏览器为了管理应用程序窗口中不同的页面每个标签页在自己的进程中渲染 从而限制了一个网页上的有误或恶意代码可能导致的对整个应用程序造成的伤害。
在Electron中我们可控制的两类进程为主进程 和 渲染进程。
1、主进程main
1️⃣ 运行环境node.js具有 require 模块和使用所有 Node.js API
2️⃣ 职责
窗口管理创建 / 销毁窗口实例BrowserWindow其相当于一个小的EventEmitter窗口将在单独的渲染器进程中加载一个网页。窗口中的webContents 代表的是 渲染进程 内部的网页内容Web 页面可以执行向渲染进程通信、网页内容生命周期监听、访问/控制devtools等
// main.js
const { BrowserWindow } require(electron)const win new BrowserWindow({ width: 800, height: 1500 })
win.loadURL(https://github.com)const contents win.webContents
console.log(contents)
应用程序的生命周期监听app生命周期、做相应处理
// quitting the app when no windows are open on non-macOS platforms
app.on(window-all-closed, () {if (process.platform ! darwin) app.quit()
})
调用api与操作系统交互Electron 有着多种控制原生桌面功能的模块例如菜单、对话框以及托盘图标。下面举个例子创建应用菜单
const { app, Menu, BrowserWindow } require(electron);app.whenReady().then(() {const win new BrowserWindow({width: 800,height: 600,webPreferences: {nodeIntegration: true}});win.loadURL(https://example.com);// 创建菜单templateconst menuTemplate [{label: 文件,submenu: [{ label: 打开文件, click: () console.log(打开文件) },{ type: separator }, // 分割线{ label: 退出, role: quit }]},{label: 编辑,submenu: [{ label: 撤销, role: undo },{ label: 重做, role: redo },{ type: separator },{ label: 剪切, role: cut },{ label: 复制, role: copy },{ label: 粘贴, role: paste }]}];// 设置应用菜单const menu Menu.buildFromTemplate(menuTemplate); //从模版设置菜单实例Menu.setApplicationMenu(menu); // 放入应用菜单
}); 2、渲染进程renderer
1️⃣ 运行环境渲染器负责 渲染 网页内容。 所以实际上运行于渲染器进程中的代码是须遵照网页web标准的。 二、预加载脚本
由于主进程和渲染进程的运行环境完全不同且默认情况下二者无权直接访问互相之间的环境。
所以出现了预加载脚本preload.js作为环境桥梁它包含了那些执行于渲染器进程中且先于网页内容开始加载的代码与浏览器共享一个全局window接口 。 这些脚本虽运行于渲染器的环境中却因能访问 Node.js API 而拥有了更多的权限。
preload.js可以部分暴露一些api给对方进程、可以作为通信中转站等等。 三、沙盒化
当 Electron 中的渲染进程被沙盒化时它们的行为与常规 Chrome 渲染器一样。 一个沙盒化的渲染器不会有一个 Node.js 环境。
附属于沙盒化的渲染进程的 preload 脚本中仍可使用一部分以 Polyfill 形式实现的 Node.js API。
为单个进程禁用沙盒
app.whenReady().then(() {const win new BrowserWindow({webPreferences: {sandbox: false}})win.loadURL(https://google.com)
})
全局启用沙盒
app.enableSandbox 注意此 API 必须在应用的 ready 事件之前调用
app.enableSandbox()
app.whenReady().then(() }// 因为调用了app.enableSandbox()所以任何sandbox:false的调用都会被覆盖。const win new BrowserWindow()win.loadURL(https://google.com)
})
四、环境访问权限控制contextIsolation和nodeIntegration
在创建一个browserWindow实例的时候会配置webPreferences中的字段。
其中有两个字段与渲染进程的访问权限密切相关contextIsolation 和 nodeIntegration
1、contextIsolation
控制 window 对象是否在独立的 JavaScript 上下文中运行。默认值true如果为true,代表渲染进程在独立的js上下文中。因此preload.js、第三方库都不能直接修改渲染进程中的window全局对象如果为falsepreload.js可以直接通过修改window属性传递值
那么不同设置下如何借助预加载脚本让主进程与渲染进程通信呢
启用contextIsolationtrue时默认推荐做法
main.js
const { BrowserWindow } require(electron);
const win new BrowserWindow({webPreferences: {contextIsolation: true, // 开启上下文隔离preload: preload.js}
});
preload.js利用exposeInMainWorld将属性挂在window对象中
const { contextBridge } require(electron);contextBridge.exposeInMainWorld(myAPI, {sayHello: () console.log(Hello!)
});
renderer.js
console.log(window.myAPI.sayHello()); // ✅ Hello!
不启用contextIsolationfalse时
preload.js可直接篡改window对象
window.myApi {sayHello: () console.log(Hello!)
}; 2、nodeIntegration
控制是否可以在渲染进程中直接使用Node.js API如fs、path、require等语法和api)默认值false无法直接使用node环境 如果启用nodeIntegration: true不推荐
渲染进程中的js文件
// 渲染进程 index.html
scriptconst fs require(fs);fs.writeFileSync(test.txt, Hello, Electron!);
/script
如果不启用我们应该如何借助Node.js的功能呢
通过【 预加载脚本】执行ipcRenderer通信发送至主进程处理 preload.js
// preload.js
const { contextBridge, ipcRenderer } require(electron);contextBridge.exposeInMainWorld(electronAPI, {sendTitle: (title) ipcRenderer.send(set-title, title),readFile : (filePath) ipcRenderer.invoke(read-file, filePath)
});
main.js的利用ipcMain接受处理函数
const { app, BrowserWindow, ipcMain } require(electron/main)
const path require(node:path)
const fs require(fs).promises;function createWindow () {const mainWindow new BrowserWindow({webPreferences: {preload: path.join(__dirname, preload.js)}})// send sendTitle方法的接收器ipcMain.on(set-title, (event, title) {//通过event.sender获取网页内容对象const webContents event.sender// fromWebContents解析const win BrowserWindow.fromWebContents(webContents)win.setTitle(title)})// invoke readFile方法的处理器ipcMain.handle(read-file, async (_, filePath) {try {const data await fs.readFile(filePath, utf-8);return { success: true, data };} catch (error) {return { success: false, error: error.message };}});mainWindow.loadFile(index.html)
}app.whenReady().then(() {createWindow()app.on(activate, function () {if (BrowserWindow.getAllWindows().length 0) createWindow()})
})app.on(window-all-closed, function () {if (process.platform ! darwin) app.quit()
}) ⚠️注意send on和invoke handle两种通信方法的区别 send on单向通信单向发送-单边处理 invoke handle 双向通信发送者发送信息 - 接收者理后可return一个返回值 - 发送者接收到返回值的Promise对象可针对返回值再处理 推荐实践
启用 sandbox: true沙箱模式进一步增强安全性
const win new BrowserWindow({webPreferences: {contextIsolation: true, 默认无需特别设置nodeIntegration: false,默认无需特别设置preload: preload.js,sandbox: true}
});