当前位置: 首页 > news >正文

【Electron入门】进程环境和隔离

目录

一、主进程和渲染进程

1、主进程(main)

2、渲染进程(renderer)

二、预加载脚本

三、沙盒化

为单个进程禁用沙盒

全局启用沙盒

四、环境访问权限控制:contextIsolation和nodeIntegration

1、contextIsolation

🌰启用contextIsolation:true时(默认推荐做法)

🌰不启用contextIsolation:false时

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全局对象;如果为false,preload.js可以直接通过修改window属性传递值

那么不同设置下,如何借助预加载脚本让主进程与渲染进程通信呢?

🌰启用contextIsolation:true时(默认推荐做法)

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!"
🌰不启用contextIsolation:false时

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
<script>const 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}
});

相关文章:

【Electron入门】进程环境和隔离

目录 一、主进程和渲染进程 1、主进程&#xff08;main&#xff09; 2、渲染进程&#xff08;renderer&#xff09; 二、预加载脚本 三、沙盒化 为单个进程禁用沙盒 全局启用沙盒 四、环境访问权限控制&#xff1a;contextIsolation和nodeIntegration 1、contextIsola…...

提示词框架介绍和使用场景

框架介绍 CO-STAR 框架 定义 CO-STAR是六个关键要素的缩写,每个字母代表一个特定的部分: Context(上下文) :提供任务的背景信息或环境 当前任务是为一家科技公司撰写一篇关于人工智能发展趋势的文章/ 需要为一场面向高中生的科普讲座准备内容Objective(目标) :明确任…...

牛客NC288803 和+和

​import java.util.Comparator;import java.util.PriorityQueue;import java.util.Scanner;​public class Main {public static void main(String[] args) {// 创建Scanner对象用于读取输入Scanner sc new Scanner(System.in);// 读取两个整数n和m&#xff0c;分别表示数组的…...

AI学习第七天

数组&#xff1a;基础概念、存储特性及力扣实战应用 在计算机科学与数学的广袤领域中&#xff0c;数组作为一种极为重要的数据结构&#xff0c;发挥着不可或缺的作用。它就像一个有序的 “数据仓库”&#xff0c;能高效地存储和管理大量数据。接下来&#xff0c;让我们深入了解…...

【uniapp原生】实时记录接口请求延迟,并生成写入文件到安卓设备

在开发实时数据监控应用时&#xff0c;记录接口请求的延迟对于性能分析和用户体验优化至关重要。本文将基于 UniApp 框架&#xff0c;介绍如何实现一个实时记录接口请求延迟的功能&#xff0c;并深入解析相关代码的实现细节。 前期准备&必要的理解 1. 功能概述 该功能的…...

XR应用测试:探索虚拟与现实的边界

引言 随着XR&#xff08;扩展现实&#xff0c;Extended Reality&#xff09;技术的快速发展&#xff0c;VR&#xff08;虚拟现实&#xff09;、AR&#xff08;增强现实&#xff09;和MR&#xff08;混合现实&#xff09;应用逐渐渗透到游戏、教育、医疗、工业等多个领域。对于…...

算法之算法思想

算法思想 ♥算法思想知识体系详解♥ | Java 全栈知识体系 经典算法思想总结 经典算法思想总结&#xff08;含LeetCode题目推荐&#xff09; | JavaGuide...

mac电脑中使用无线诊断.app查看连接的Wi-Fi带宽

问题 需要检查连接到的Wi-Fi的AP硬件支持的带宽。 步骤 1.按住 Option 键&#xff0c;然后点击屏幕顶部的Wi-Fi图标&#xff1b;2.从下拉菜单中选择 “打开无线诊断”&#xff08;Open Wireless Diagnostics&#xff09;&#xff1b;3.你可能会看到一个提示窗口&#xff0c;…...

物理竞赛中的线性代数

线性代数 1 行列式 1.1 n n n 阶行列式 定义 1.1.1&#xff1a;称以下的式子为一个 n n n 阶行列式&#xff1a; ∣ A ∣ ∣ a 11 a 12 ⋯ a 1 n a 21 a 22 ⋯ a 2 n ⋮ ⋮ ⋱ ⋮ a n 1 a n 2 ⋯ a n n ∣ \begin{vmatrix}\mathbf A\end{vmatrix} \begin{vmatrix} a_{11…...

FFmpeg-chapter3-读取视频流(原理篇)

ffmpeg网站&#xff1a;About FFmpeg 1 库介绍 &#xff08;1&#xff09;libavutil是一个包含简化编程函数的库&#xff0c;包括随机数生成器、数据结构、数学例程、核心多媒体实用程序等等。 &#xff08;2&#xff09;libavcodec是一个包含音频/视频编解码器的解码器和编…...

机器视觉线阵相机分时频闪选型/机器视觉线阵相机分时频闪选型

在机器视觉系统中,线阵相机的分时频闪技术通过单次扫描切换不同光源或亮度,实现在一幅图像中捕捉多角度光照效果,从而提升缺陷检测效率并降低成本。以下是分时频闪线阵相机的选型要点及关键考量因素: 一、分时频闪技术的核心需求 多光源同步控制 分时频闪需相机支持多路光源…...

「Selenium+Python自动化从0到1②|2025浏览器操控7大核心API实战(附高效避坑模板))」

Python 自动化操作浏览器基础方法 在进行 Web 自动化测试时&#xff0c;操作浏览器是必不可少的环节。Python 结合 Selenium 提供了强大的浏览器操作功能&#xff0c;让我们能够轻松地控制浏览器执行各种任务。本文将详细介绍如何使用 Python 和 Selenium 操作浏览器的基本方法…...

矩阵系列 题解

1.洛谷 P1962 斐波那契数列 题意 大家都知道&#xff0c;斐波那契数列是满足如下性质的一个数列&#xff1a; F n { 1 ( n ≤ 2 ) F n − 1 F n − 2 ( n ≥ 3 ) F_n \left\{\begin{aligned} 1 \space (n \le 2) \\ F_{n-1}F_{n-2} \space (n\ge 3) \end{aligned}\right. …...

活动报名:Voice Agent 技术现状及应用展望丨 3.8 北京

「人人发言&#xff0c;所有人向所有人学习&#xff01;」——Z 沙龙 「一起探索下一代语音驱动的人机交互界面。」——RTE 开发者社区 3 月 8 日周六下午&#xff0c;北京&#xff0c;「智谱 Z 计划&Z Fund」和「RTE 开发者社区」将合办一场 Voice Agent 主题的线下活动…...

【卡牌——二分】

题目 分析 发现答案具有二分性&#xff0c;果断二分答案 代码 #include <bits/stdc.h> using namespace std; using ll long long;const int N 2e510;int n, a[N], li[N]; ll m;bool check(int x) {ll t m;for(int i 1; i < n; i){if(a[i] > x) continue; //…...

《第十五部分》STM32之FLASH闪存(终结篇)

本章是江科大自学STM32的最后一章节&#xff0c;历经2个月的断断续续时间&#xff0c;终于学到了最后&#xff0c;总结&#xff0c;这次的学习历程&#xff0c;相对于学习51还是略出一些难度&#xff0c;也就是若你是非科班&#xff0c;学习起来还是有一定的难度的&#xff0c;…...

属性的设置

笔记 class Student:def __init__(self, name, gender):self.name nameself.__gender gender # self.__gender 是私有的实例属性# 使用property 修改方法&#xff0c;将方法转成属性使用propertydef gender(self):return self.__gender# 将我们的gender这个属性设置为可写属…...

本地部署Deepseek+Cherry Studio

为啥要本地部署deepseek&#xff1f; 因为给deepseek发送指令得到服务器繁忙的回馈&#xff0c;本地部署会运行的更快 1.Ollama安装与部署 Ollama是一个开源框架&#xff0c;专为在本地机器上便捷部署和运行大型语言模型&#xff08;LLM&#xff09;而设计 winR——cmd——ol…...

CMU15445(2023fall) Project #2 - Extendible Hash Index 匠心分析

胡未灭&#xff0c;鬓已秋&#xff0c;泪空流 此生谁料 心在天山 身老沧州 ——诉衷情 完整代码见&#xff1a; SnowLegend-star/CMU15445-2023fall: Having Conquered the Loftiest Peak, We Stand But a Step Away from Victory in This Stage. With unwavering determinati…...

【VSCode】VSCode下载安装与配置极简描述

VSCode 参考网址&#xff1a;[Visual Studio Code Guide | GZTime’s Blog]. 下载安装 下载地址&#xff1a;Download Visual Studio Code - Mac, Linux, Windows. 注&#xff1a;推荐不更改安装位置&#xff0c;并且在附加任务中“其他”中的四项全部勾选&#xff0c;即将用…...

Docker 离线安装指南

参考文章 1、确认操作系统类型及内核版本 Docker依赖于Linux内核的一些特性&#xff0c;不同版本的Docker对内核版本有不同要求。例如&#xff0c;Docker 17.06及之后的版本通常需要Linux内核3.10及以上版本&#xff0c;Docker17.09及更高版本对应Linux内核4.9.x及更高版本。…...

【Linux】shell脚本忽略错误继续执行

在 shell 脚本中&#xff0c;可以使用 set -e 命令来设置脚本在遇到错误时退出执行。如果你希望脚本忽略错误并继续执行&#xff0c;可以在脚本开头添加 set e 命令来取消该设置。 举例1 #!/bin/bash# 取消 set -e 的设置 set e# 执行命令&#xff0c;并忽略错误 rm somefile…...

golang循环变量捕获问题​​

在 Go 语言中&#xff0c;当在循环中启动协程&#xff08;goroutine&#xff09;时&#xff0c;如果在协程闭包中直接引用循环变量&#xff0c;可能会遇到一个常见的陷阱 - ​​循环变量捕获问题​​。让我详细解释一下&#xff1a; 问题背景 看这个代码片段&#xff1a; fo…...

【Java学习笔记】Arrays类

Arrays 类 1. 导入包&#xff1a;import java.util.Arrays 2. 常用方法一览表 方法描述Arrays.toString()返回数组的字符串形式Arrays.sort()排序&#xff08;自然排序和定制排序&#xff09;Arrays.binarySearch()通过二分搜索法进行查找&#xff08;前提&#xff1a;数组是…...

如何在看板中体现优先级变化

在看板中有效体现优先级变化的关键措施包括&#xff1a;采用颜色或标签标识优先级、设置任务排序规则、使用独立的优先级列或泳道、结合自动化规则同步优先级变化、建立定期的优先级审查流程。其中&#xff0c;设置任务排序规则尤其重要&#xff0c;因为它让看板视觉上直观地体…...

【解密LSTM、GRU如何解决传统RNN梯度消失问题】

解密LSTM与GRU&#xff1a;如何让RNN变得更聪明&#xff1f; 在深度学习的世界里&#xff0c;循环神经网络&#xff08;RNN&#xff09;以其卓越的序列数据处理能力广泛应用于自然语言处理、时间序列预测等领域。然而&#xff0c;传统RNN存在的一个严重问题——梯度消失&#…...

vue3 字体颜色设置的多种方式

在Vue 3中设置字体颜色可以通过多种方式实现&#xff0c;这取决于你是想在组件内部直接设置&#xff0c;还是在CSS/SCSS/LESS等样式文件中定义。以下是几种常见的方法&#xff1a; 1. 内联样式 你可以直接在模板中使用style绑定来设置字体颜色。 <template><div :s…...

Java多线程实现之Callable接口深度解析

Java多线程实现之Callable接口深度解析 一、Callable接口概述1.1 接口定义1.2 与Runnable接口的对比1.3 Future接口与FutureTask类 二、Callable接口的基本使用方法2.1 传统方式实现Callable接口2.2 使用Lambda表达式简化Callable实现2.3 使用FutureTask类执行Callable任务 三、…...

【android bluetooth 框架分析 04】【bt-framework 层详解 1】【BluetoothProperties介绍】

1. BluetoothProperties介绍 libsysprop/srcs/android/sysprop/BluetoothProperties.sysprop BluetoothProperties.sysprop 是 Android AOSP 中的一种 系统属性定义文件&#xff08;System Property Definition File&#xff09;&#xff0c;用于声明和管理 Bluetooth 模块相…...

Cloudflare 从 Nginx 到 Pingora:性能、效率与安全的全面升级

在互联网的快速发展中&#xff0c;高性能、高效率和高安全性的网络服务成为了各大互联网基础设施提供商的核心追求。Cloudflare 作为全球领先的互联网安全和基础设施公司&#xff0c;近期做出了一个重大技术决策&#xff1a;弃用长期使用的 Nginx&#xff0c;转而采用其内部开发…...