Electron基礎篇

人生有些事,錯過一時,就錯過一世。


?官網:簡介 | Electron

Electron-大多用來寫桌面端軟件

?


Electron介紹

Electront的核心組成是Chromium、Node.js以及內置的Native API,其中Chromium為Electron提供強大的UI能力,可以在不考慮兼容的情況下利用強大的Web生態來開發界面;Node.js讓Electron有了底層的操作能力,比如像文件的讀寫,然后集成C++等等,還可以使用大量的NPM包來幫助大家來完成項目需求;最后內置的Native API解決了跨平臺的問題,首先它提供了統一的原生界面,比如像窗口、托盤,其次是系統能力,比如像我們的Notification,最后是應用的基礎能力,比如像軟件更新,崩潰監控等等,而通過這三者的組合,我們開發桌面應用變得十分的高效。

基礎介紹

1、Electron是什么?
Electron 是 GitHub 開發的一個開源框架。它允許開發者使用Web技術構建跨平臺桌面應用。

在這里插入圖片描述

高效:通過Web技術寫UI  
能力:底層能力  
能力&體驗:跨平臺&原生能力

桌面技術選型
1、為什么開發桌面端?
① 提供更快捷的入口,讓自己的產品占據用戶的桌面;
② 軟件需要離線可用;
③ 需要調用到系統能力,比如像通知用戶,然后結合打印機去完成自己的業務等等
④ 安全需求,比如在金融或企業級應用領域下,我們會更偏向于做一個桌面端

2、技術
1)Native(C++/C#/Objective-C)
各平臺的原生語言寫的應用在高性能、原生體驗、包體積小、門檻高、迭代速度慢。

2)QT
基于C++的跨平臺開發框架(Mac、Windows、IOS、Android、Linux、嵌入式)應用十分廣泛,像大家熟知的DropBox或者WPS,它都是用QT來寫的;雖然是跨平臺,但實際(高)性能還挺好,它甚至可以媲美原生(體驗);QT它有著自己的QML,類似CSS,也有不錯的社區和生態,所以迭代速度會比Native會快一些,但是整體門檻還是比較高,而且人才在市場上比較稀缺。

3)Flutter
Flutter是移動端非常火的,它的整體的目標是跨端(iOS、Android、Mac、Windows、Linux、Web),PC端在發展中(Mac>Linux、Windows),在Linux和Windows上是基本不可用的狀態,基建也特別少,所以目前來說是不太適用用做業務的,但是可以保持關注。

4)NW.js
Web技術代表包括NW.js和Electron,NW.js它跟Electron特別像,它一樣是跨平臺(Mac、Windows、Linux),基于Web來做桌面端,V0.14.7支持XP(XP市場份額約為15%),NW.js做的比較好的它支持了一個源碼的加密,然后支持Chrome的擴展;它有不錯的社區,但是它也有這Electron一樣的缺陷,就是包體積會比較大、性能一般,代表作有微信開發工具。

5)Electron
它是一個跨平臺框架(Mac、Windows、Linux、不支持XP),有著非常活躍的社區,如下圖作為案例。在包體積中,因為Electron將整個Chromium都打進去了,所以哪怕你的代碼只有一行Hello World,包體積也會達到50M,同時性能相比Native和QT都會差一些。

more…

在這里插入圖片描述

?技術架構與原理

1、Chromium架構:
了解Electron的架構和原理、Electron的多進程架構以及我們的Chromium和Node.js是怎么一起工作的。Electron是基于Chromium做的,如果想了解Electron得先了解Chromium架構,如下圖為Chromium架構:

在這里插入圖片描述

?Chromium本質是Chrome的開源版,也是一個瀏覽器,瀏覽器也是一個桌面應用,它需要去創建窗口、右鍵菜單、管理瀏覽器Tab頁面還有擴展程序等等,而處理這些事項的進程,我們稱它為主進程,也就是如圖中的Browser,而對應每個具體頁面的進程,我們稱它為渲染進程,對應的就是Render。在一個瀏覽器里面,它會有一個Browser,多個頁面,而這兩個進程需要通信交互才能運轉的,如果大家對Linux或者進程有一定了解,兩個進程它就需要跨進程通信,也就是所謂的IPC。我們主進程的RendererProcessHost以及Render進程的RenderProcess就是專門用來處理IPC事件。接下來將一下渲染進程具體內容,首先是RenderView,我們最熟悉的頁面就是在RenderView中,基于Webkit排版展示出來的。最后只剩下一個ResourceDispatcher,是用來處理我們的資源請求,當我們的頁面需要請求資源的時候,會通過ResourceDispatcher,然后創建一個請求ID,然后轉發到我們的IPC,在我們的Browser進程里處理然后返回。本質上圖帶給我們有三點分別是:
① Chromium是多進程架構,包括Browser和多個Render;
② 進程間是需要IPC通信;
③ 我們Web關注到的只是很小一部分
2、Electron架構:
接下來我們來看一下Electron的大體架構,如下圖:

在這里插入圖片描述

?

由于Electron使用了Chromium來展示Web頁面,所以Chromium的多進程架構也會被使用到Electron,在Electron中也分為主進程、渲染進程,但是跟Chromium不一樣的有兩點:① 我們在各個進程里暴露了一些Native API;② 我們引入了Node.js,于是我們在Electron中,可以使用Chromium和Node,比如我們可以通過Node去管理窗口,然后在頁面中我們可以使用Node庫。其實這很不容易的,因為在主線程中同一個時間下,只能運行一個事件循環,但是Node.js它的事件循環是基于libuv,但Chromium基于message bump,這就是Electron原理的重點就是如何整合事件循環:①Chromium的messagebump用libuv實現一次,比如像NW.js就是這么做的。②Node.js集成到Chromium。

可以簡單的理解為Electron為web項目套上了Node.js環境的殼,使得我們可以調用Node.js的豐富的API。這樣我們可以用JavaScript來寫桌面應用,拓展很多我們在web端不能做的事情。
在這里插入圖片描述

?

Electron 快速上手

1、 初始化工程

創建 Electron 工程方式與前端項目別無二致,創建一個目錄,然后用 npm 初始化:

mkdir hello-electron && cd hello-electron
npm init -y
?

生成之后的 package.json 應該長這樣。

{"name": "hello-electron","version": "1.0.0","description": "","main": "index.js","scripts": {"test": "echo \"Error: no test specified\" && exit 1"},"keywords": [],"author": "","license": "ISC"
}

2、安裝依賴

npm install --save-dev electron
?

安裝過程中,electron 模塊會去 Github 下載 預編譯二進制文件,然而下載速度大家都懂的,可能會出現下載失敗的情況。這里可以使用 taobao 的鏡像源來下載。

npm config set electron_mirror http://npm.taobao.org/mirrors/electron/
npm config set electron_custom_dir "8.1.1"
?

為了更方便的啟動我們的程序,可以新增一條命令。

{"scripts": {"start": "electron ."}
}

接下來,就讓我們愉快地編碼吧。

3、創建 HTML

在 Electron 中,每個窗口都可以加載本地或者遠程 URL,這里我們先創建一個本地的 HTML 文件。

<!DOCTYPE html>
<html>
? <head>
? ? <meta charset="UTF-8">
? ? <title>Hello World!</title>
? </head>
? <body>
? ? <h1>Hello World!</h1>
? ? We are using Electron <span id="electron-version"></span>
? </body>
</html>

這里你可能會注意到, span 標簽里面是空文本,后面我們會動態插入 Electron 的版本。

4、創建入口文件
類似于 Node.js 啟動服務,Electron 啟動也需要一個入口文件,這里我們創建 index.js 文件。在這個入口文件里,需要去加載上面創建的 HTML 文件,那么如何加載呢? Electron 提供了兩個模塊:

-- app 模塊,它控制應用程序的事件生命周期。
-- BrowserWindow 模塊,它創建和管理應用程序 窗口。
入口文件是 Node.js 環境,所以可以通過 CommonJS 模塊規范來導入 Electron 的模塊。同時添加一個 createWindow() 方法來將 index.html 加載進一個新的 BrowserWindow 實例。
?

// index.js
const { app, BrowserWindow } = require('electron');
function createWindow () {
? const win = new BrowserWindow({
? ? width: 800,
? ? height: 600
? })
? win.loadFile('index.html')
}
?

那么在什么時候調用createWindow方法來打開窗口呢?在 Electron 中,只有在?app?模塊的 ready 事件被激發后才能創建瀏覽器窗口。可以通過使用app.whenReady()?API 來監聽此事件。

?// index.js
app.whenReady().then(() => {
? createWindow()
})

這樣一來就可以通過以下命令打開Electron應用程序了!

// 這里會自動去找package.json的main字段對應的文件運行
// 當然 你也可以將命令放進 script 里面
npx electron .

?

運行完打開的應用程序如下圖所示。
圖片

5、管理窗口的聲明周期
雖然現在可以打開一個瀏覽器窗口,但還需要一些額外的模板代碼使其看起來更像是各平臺原生的。應用程序窗口在每個 OS 下有不同的行為,Electron 將在 app 中實現這些約定的責任交給開發者們。可以使用 process.platform屬性來為不同的操作系統做處理。

(1)關閉所有窗口時退出應用(Windows & Linux)
在 Windows 和 Linux 上,關閉所有窗口通常會完全退出一個應用程序。 app 模塊可以監聽所有窗口關閉的事件 window-all-closed,在事件回調里可以調用 app.quit() 退出應用。

// index.js
app.on('window-all-closed', function () {
? // darwin 為 macOS
? if (process.platform !== 'darwin') app.quit()
})
?

(2)沒有窗口打開則打開一個新窗口(macOS)
用過 macOS 的人應該都知道,一個應用沒有窗口打開的時候,也是可以繼續運行的,這時如果打開應用程序,就會打開新的窗口。 app 模塊可以監聽應用激活事件 activate,在事件回調里可以判斷當前窗口數量來確定需不需要打開一個新的窗口。因為窗口無法在 ready 事件前創建,你應當在你的應用初始化后僅監聽 activate 事件。通過在您現有的 whenReady() 回調中附上您的事件監聽器來完成這個操作。
?

// index.js
app.whenReady().then(() => {
? createWindow()

? app.on('activate', function () {
? ? if (BrowserWindow.getAllWindows().length === 0) createWindow()
? })
})
?

6、預加載腳本

前面講到我們會在?HTML?文件中插入?Electron?的版本號。然而,在?index.js?主進程中,是不能編輯?DOM?的,因為它無法訪問到渲染進程?document?上下文,它們存在于完全不同的進程中。

? ? ?這時候,預加載腳本就可以派上用場了。預加載腳本在渲染進程加載之前加載,并有權訪問兩個渲染進程全局 (例如?window?和?document) 和?Node.js?環境。

(1)創建預加載腳本
創建一個名為 preload.js 的新腳本如下:

window.addEventListener('DOMContentLoaded', () => {
? const replaceText = (selector, text) => {
? ? const element = document.getElementById(selector);
? ? if (element) element.innerText = text;
? }
??
? replaceText('electron-version', process.versions.electron);
})
?

我們需要在初始化 BrowserWindow 實例的時候,傳入該預加載腳本。

// 在文件頭部引入 Node.js 中的 path 模塊
const path = require('path')
// 修改現有的 createWindow() 函數
function createWindow () {const win = new BrowserWindow({width: 800,height: 600,webPreferences: {preload: path.join(__dirname, 'preload.js')}})win.loadFile('index.html')
}
// ...

然后重新啟動程序,就可以看到 Electron 的版本了。
?

圖片

?

Electron 的流程模型
前面講到了主進程、渲染進程等概念性知識,初學者可能會對此比較迷惑,不過,進行 Electron,對這一塊內容的掌握是至關重要的,后面的 IPC 進程通信,也與此有關。實際上,Electron繼承了來自 Chromium 的多進程架構,作為工程師,對于瀏覽器進程架構有所了解,也是非常有必要的。

1、主進程
每個 Electron 應用都有一個單一的主進程,作為應用程序的入口點,比如上面的 index.js。主進程在 Node.js 環境中運行,這意味著它具有 require 模塊和使用所有 Node.js API 的能力。主進程一般包括以下三大塊:

-- 窗口管理:使用 BrowserWindow 模塊創建和管理應用窗口。類的每個實例創建一個應用程序窗口,且在單獨的渲染器進程中加載一個網頁。
-- 應用生命周期:主進程可以使用 Electron 提供的 app 模塊來控制應用程序的生命周期。
-- 原生 API: Electron 有著多種控制原生桌面功能的模塊,例如菜單、對話框以及托盤圖標。
?

2、渲染進程
每個打開的BrowserWindow都會生成一個單獨的渲染進程。渲染進程負責渲染網頁實際的內容。因此,渲染進程中運行的代碼,幾乎跟我們編寫的 Web 代碼別無二致。除此之外,渲染進程也無法直接訪問 require或其他Node.js API。

注意:實際上渲染進程可以生成一個完整的 Node.js 環境以便于開發。在過去這是默認的,但如今此功能考慮到安全問題已經被禁用。
?

3、預加載腳本
前面上手的時候已經講過預加載腳本了,預加載(preload)腳本會在渲染進程網頁內容開始加載之前執行,并且可以訪問 Node.js API。由于預加載腳本與渲染器共享同一個全局 Window 接口,因此它通過在 window 全局中暴露任意您的網絡內容可以隨后使用的 API 來增強渲染器。

不過我們不能在預加載腳本中直接給?window?掛載變量,因為contextIsolation是默認的。

?window.myAPI = { desktop: true }
console.log(window.myAPI) // => undefined

Electron這樣做是為了將預加載腳本與渲染進程的主要運行環境隔離開來的,以避免泄漏任何具特權的 API 到網頁內容代碼中。(比如有些人會把ipcRenderer.send的方法暴露給web 端,這將允許網站發送任意的 IPC 消息)

我們也可以關閉contextIsolation,不過不建議這么做。
new BrowserWindow({
? // ...
? webPreferences: {
? ? ? // ...
? ? contextIsolation: false
? }
})
?

最好使用contextBridge?模塊來安全地實現交互:

const { contextBridge } = require('electron')
contextBridge.exposeInMainWorld('myAPI', {
? desktop: true
})
console.log(window.myAPI)// => { desktop: true }
?

Electron IPC 通信

Electron?有主進程和渲染進程,之間會有許多通信,這樣就涉及到了進程間通信(IPC,InterProcess Communication)。在Electron中,主線程和渲染進程之間進行通信,只要是用到以下兩個模塊:

-- ipcMain : ipcMain是一個 EventEmitter的實例。當在主進程中使用時,它處理從渲染器進程(網頁)發送出來的異步和同步信息。從渲染器進程發送的消息將被發送到該模塊。
-- ipcRenderer: ipcRenderer是一個 EventEmitter的實例。你可以使用它提供的一些方法從渲染進程 (web 頁面) 發送同步或異步的消息到主進程。也可以接收主進程回復的消息。

1、渲染進程給主線程發送消息,主線程回復

(1)普通腳本監聽
普通腳本引入 electron 的 ipcRenderer 模塊,實現發送消息。

在 HTML 文件添加 renderer.js 腳本

const { ipcRenderer } = require('electron')
ipcRenderer.on('main-message-reply', (event, arg) => {
? console.log(arg);
});
ipcRenderer.send('message-from-renderer', '渲染進程發送消息過來了');
?

在 index.js 入口文件引入 ipcMain 模塊,并修改 BrowserWindow 的實例化參數,開啟渲染進程的 Node.js 環境。

const { ipcMain } = require('electron')
function createWindow() {const mainWindow = new BrowserWindow({width: 800,height: 600,webPreferences: {preload: path.join(__dirname, 'preload.js'),// 這里開啟后 渲染進程就可以用 NodeJS 環境// 可以引如 Electron 相關模塊nodeIntegration: true,contextIsolation: false,},});mainWindow.loadFile('index.html');
}ipcMain.on('message-from-renderer', (event, arg) => {console.log(arg);// 接收到消息后可以回復event.reply('main-message-reply', '主進程回復了')
})

啟動應用,可以在命令行看到渲染進程發過來的消息了。

圖片

?圖片

?(2)預加載腳本暴露接口
在預加載腳本中,可以暴露一些全局的接口給到渲染進程,然后渲染進程調用,從而達到通信的目的。這種方式類似于微信 SDK,不用侵入到前端腳本去監聽事件,較為安全。

// preload.js
const { contextBridge, ipcRenderer } = require('electron')

// 這里暴露一個全局myAPI變量
contextBridge.exposeInMainWorld('myAPI', {
? getMessage(args) {
? ? ? ipcRenderer.send('message-from-proload', args);
? ? ? consoloe.log('前端調用了:', args)
? }
})
?

renderer.js直接調用暴露出來的接口。

// renderer.js
window.myAPI.getMessage('postMessage');
?

index.js主進程監聽預加載腳本發送過來的信息。

ipcMain.on('message-from-proload', (event, arg) => {
? console.log(arg);
? // 接收到消息后可以回復
? event.reply('main-message-reply', '主進程回復了')
})
?

2、主線程給渲染進程發送消息

renderer.js改為如下代碼,監聽主線程發送過來的消息。

const { ipcRenderer } = require("electron");

ipcRenderer.on("message", (event, arg) => {
? console.log("主進程主動推消息了:", arg);
});
?

主線程往渲染進程發送消息,需要用到 webContents。?webContents是一個 EventEmitter,負責渲染和控制網頁,是BrowserWindow對象的一個屬性。修改一下index.js?文件。

function createWindow() {
? const mainWindow = new BrowserWindow({
? ? width: 800,
? ? height: 600,
? ? webPreferences: {
? ? ? preload: path.join(__dirname, 'preload.js'),
? ? ? nodeIntegration: true,
? ? ? contextIsolation: false,
? ? },
? });

? const contents = mainWindow.webContents;
? mainWindow.loadFile('index.html');
? contents.openDevTools(); //打開調試工具

? contents.on("did-finish-load", () => {
? ? //頁面加載完成觸發的回調函數
? ? contents.send("main-message-reply", "我看到你加載完了,給你發個信息");
? });
}


?

運行應用,就可以在渲染進程中打開看到消息了。
在這里插入圖片描述

?

以上的通信方式均為異步,不過 Electron也提供了同步的通信方式,但是同步的方式會阻塞代碼的執行,最好都使用異步通信。同步用法在這里不多作介紹。

ipcMain和ipcRenderer模塊還有一些其他的通信 API,不過大抵都是類似的通信方式,需要了解的同學可以自行去查閱文檔。
?

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/42621.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/42621.shtml
英文地址,請注明出處:http://en.pswp.cn/news/42621.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

使用神卓互聯內網穿透搭建遠程訪問公司ERP系統

神卓互聯是一款企業級內網穿透軟件&#xff0c;可以將內網中的服務映射到公網上&#xff0c;實現內網服務的訪問。通過神卓互聯&#xff0c;您可以遠程訪問ERP系統。在使用神卓互聯進行內網穿透時&#xff0c;您只需要在生成的公網地址后面加上ERP系統的端口號&#xff0c;即可…

NVIDIA vGPU License許可服務器高可用全套部署秘籍

第1章 前言 近期遇到比較多的場景使用vGPU&#xff0c;比如Citrix 3D場景、Horizon 3D場景&#xff0c;還有AI等&#xff0c;都需要使用顯卡設計研發等&#xff0c;此時許可服務器尤為重要&#xff0c;許可斷掉會出現掉幀等情況&#xff0c;我們此次教大家部署HA許可服務器。 …

【.net】本地調試運行只能用localhost的問題

【.net】本地調試運行只能用localhost的問題 解決方案 找到到項目目錄下 隱藏文件夾 .vs /項目名稱/config/applicationhost.config <bindings><binding protocol"http" bindingInformation"*:1738:localhost" /></bindings> 再加一條你…

職業學院物聯網實訓室建設方案

一、概述 1.1專業背景 物聯網&#xff08;Internet of Things&#xff09;被稱為繼計算機、互聯網之后世界信息產業第三次浪潮&#xff0c;它并非一個全新的技術領域&#xff0c;而是現代信息技術發展到一定階段后出現的一種聚合性應用與技術提升&#xff0c;是隨著傳感網、通…

如何判斷自己是否適合游戲開發?

引言 游戲開發是一個充滿創意和技術挑戰的領域&#xff0c;吸引著越來越多的年輕人投身其中。然而&#xff0c;要想在游戲開發領域獲得成功&#xff0c;首先需要明確自己是否適合這個領域。本文將為你介紹一些判斷自己是否適合游戲開發的關鍵因素。 1. 技術興趣和編程能力 游…

Python 程序設計入門(024)—— Python 的文件操作

Python 程序設計入門&#xff08;024&#xff09;—— Python 的文件操作 目錄 Python 程序設計入門&#xff08;024&#xff09;—— Python 的文件操作一、文件對象二、讀取文件內容的方法1、read() 方法2、readline() 方法3、readlines() 方法4、使用 for 循環讀取文件內容 …

麥肯錫發布《2023科技趨勢展望報告》,生成式AI、下一代軟件開發成為趨勢,軟件測試如何貼合趨勢?

近日&#xff0c;麥肯錫公司發布了《2023科技趨勢展望報告》。報告列出了15個趨勢&#xff0c;并把他們分為5大類&#xff0c;人工智能革命、構建數字未來、計算和連接的前沿、尖端工程技術和可持續發展。 類別一&#xff1a;人工智能革命 生成式AI 生成型人工智能標志著人工智…

CSRF

文章目錄 CSRF(get)CSRF(post)CSRF Token CSRF(get) 根據提示的用戶信息登錄 點擊修改個人信息 開啟bp代理&#xff0c;點擊submit 攔截到請求數據包 瀏覽器關閉代理 刷新頁面 CSRF(post) 使用BP生成CSRF POC post請求偽造&#xff0c;可以通過釣魚網站&#xff0c;誘導用戶去…

docker 常用命令大全

1.查看docker版本&#xff1a; docker -v2.檢查 Docker 是否正在運行: systemctl status docker3.重啟docker服務: systemctl restart docker4.列出本地鏡像: docker images5.列出正在運行的容器&#xff1a; docker ps6.列出所有容器&#xff08;包括停止的&#xff09;&…

css 實現文字橫向循環滾動

實現效果 思路 ## 直接上代碼,html部分 //我這里是用的uniapp <view class"weather_info_wrap"><view class"weather_info">當前多云&#xff0c;今晚8點轉晴&#xff0c;明天有雨&#xff0c;溫度32攝氏度。</view><view class&qu…

CF1005A Tanya and Stairways 題解

題目傳送門 題目意思&#xff1a; 給你 n n n 個數&#xff0c;如果第 i i i 個數小于或等于第 i ? 1 i-1 i?1 個數&#xff0c;就輸出這個數。 思路&#xff1a; 輸入后直接遍歷判斷即可。 代碼&#xff1a; #include<bits/stdc.h> using namespace std; int …

解決IDEA tomcat控制臺只有server日志

解決IDEA tomcat控制臺只有server日志 確認tomcatxxx/conf/logging.properties文件是否存在&#xff0c;存在就會有。前提是在run configuration配置了打印多個日志

uniapp封裝組件,選中后右上角顯示對號√樣式(通過css實現)

效果&#xff1a; 一、組件封裝 1、在項目根目錄下創建components文件夾&#xff0c;自定義組件名稱&#xff0c;我定義的是xc-button 2、封裝組件代碼 <template><view class"handle-btn"><view :class"handleIdCode 1 ? select : unSelec…

螞蟻數科持續發力PaaS領域,SOFAStack布局全棧軟件供應鏈安全產品

8月18日&#xff0c;記者了解到&#xff0c;螞蟻數科再度加碼云原生PaaS領域&#xff0c;SOFAStack率先完成全棧軟件供應鏈安全產品及解決方案的布局&#xff0c;包括靜態代碼掃描Pinpoint、軟件成分分析SCA、交互式安全測試IAST、運行時防護RASP、安全洞察Appinsight等&#x…

【電商領域】Axure在線購物商城小程序原型圖,品牌自營垂直電商APP原型

作品概況 頁面數量&#xff1a;共 60 頁 兼容軟件&#xff1a;Axure RP 9/10&#xff0c;不支持低版本 應用領域&#xff1a;網上商城、品牌自營商城、商城模塊插件 作品申明&#xff1a;頁面內容僅用于功能演示&#xff0c;無實際功能 作品特色 本作品為品牌自營網上商城…

無涯教程-Perl - warn函數

描述 此函數將LIST的值打印到STDERR。基本上與die函數相同,除了不對出口進行任何調用并且在eval語句內不引發異常。這對于引發錯誤而不導致腳本過早終止很有用。 如果變量$包含一個值(來自先前的eval調用),并且LIST為空,則$的值將以。\t.caught打印。附加到末尾。如果$和LIST…

MySQL數據庫概述

MySQL數據庫概述 1 SQL SQL語句大小寫不敏感。 SQL語句末尾應該使用分號結束。 1.1 SQL語句及相關操作示例 DDL&#xff1a;數據定義語言&#xff0c;負責數據庫定義、數據庫對象定義&#xff0c;由CREATE、ALTER與DROP三個語法所組成DML&#xff1a;數據操作語言&#xff…

關于小程序收集用戶手機號行為的規范

手機號在日常生活中被廣泛使用&#xff0c;是重要的用戶個人信息&#xff0c;小程序開發者應在用戶明確同意的前提下&#xff0c;依法合規地處理用戶的手機號信息。 而部分開發者在處理用戶手機號過程中&#xff0c;存在不規范收集行為&#xff0c;影響了用戶的正常使用體驗&a…

ElasticSearchConfig

1. 添加配置 <dependency><groupId>org.elasticsearch.client</groupId><artifactId>elasticsearch-rest-high-level-client</artifactId></dependency>2. es 配置信息 import org.apache.http.HttpHost; import org.apache.http.auth.Au…

k8s簡介、虛擬機快速搭建k8s集群、集群管理方式及K8S工作原理和組件介紹

文章目錄 1、k8s簡介1.1、部署方式的變遷1.2、定義1.3、Kubernetes提供的功能 2、虛擬機快速搭建k8s集群2.1、虛擬機配置&#xff08;centos7 2G內存2個處理器&#xff09;2.2、基礎環境準備2.3、docker安裝&#xff08;易踩坑&#xff09;2.4、安裝k8s組件2.5、master節點部署…