主頁 > 企業開發 > 認識 WebAssembly

認識 WebAssembly

2022-02-27 07:14:06 企業開發

起源

WebAssembly 起源于 Mozilla 員工的一個業余專案,2010年,在 Mozilla 從事 Android Firefox 開發的 Alon Zakai,為了把他以前開發的游戲引擎移植到瀏覽器上運行,利用業余時間開發了一款名叫 Emscripten 的編譯器,可以把 C++ 代碼通過 LLVM IR 編譯成 JavaScript 代碼,

到了 2011 年底,Emscripten 甚至能夠成功編譯 Python 和 Doom 等大型 C++ 專案,Mozilla 此時覺得這個專案很有前途,于是成立團隊并邀請 Alon 全職開發這個專案,2013 年 Alon 和其他成員一起提出了 asm.js 規范,asm.js 是 JavaScript 語言的一個嚴格子集,試圖通過“減少動態特性”和”添加型別提示“的方式幫助瀏覽器提升 JavaScript 優化空間,相較于完整的 JavaScript 語言,裁剪后的 asm.js 更靠近底層,更適合作為編譯器目標語言,

asm.js 只提供兩種資料型別:32位帶符號整數,64位帶符號浮點數,其他資料型別比如字串、布林值或者物件,asm.js 一概不提供,它們都是以數值的形式存在,保存在記憶體中,通過 TypedArray 呼叫,型別的宣告也有固定寫法:變數 | 0 表示整數,+變數 表示浮點數,例如下面一段代碼:

function MyAsmModule() {
    "use asm";  // 告訴瀏覽器這是個 asm.js 模塊
    function add(x, y) {
        x = x | 0;  // 變數 | 0 表示整數
        y = y | 0;
        return (x + y) | 0;
    }
    return { add: add };
}

支持 asm.js 的引擎提前識別出了型別,可以進行激進的 JIT(即時編譯)優化,甚至是 AOT(事先編譯)編譯,大幅提升性能,不支持 asm.js 按普通 JavaScript 代碼執行也不會影響運行結果,

但是 asm.js 的缺點也很明顯,那就是“底層”得不夠徹底,例如代碼仍然是文本格式;代碼撰寫仍然受 JavaScript 語法限制;瀏覽器仍然需要完成決議腳本、解釋執行、收集性能指標、JIT 編譯等一系列步驟,如果采用像 Java 類檔案那樣的二進制格式,不僅能縮小檔案體積,減少網路傳輸時間和決議時間,還能選用更接近機器的位元組碼,這樣 AOT/JIT 編譯器實作起來會更輕松,效果也更好,

與此同時,Google 的 Chrome 團隊也在試圖解決 JavaScript 性能問題,但方向有所不同,Chrome 給出的解決方案是 NaCl(Google Native Client)和 PNaCl(Portable NaCl),通過 NaCl/PNaC1,Chrome 瀏覽器可以在沙箱環境中直接執行本地代碼,

asm.js 和 NaCl/PNaC1 技術各有優缺點,二者可以取長補短,Mozilla 和 Google也看到了這一點,所以從 2013 年開始,兩個團隊就經常交流和合作,后來他們決定結合兩個專案的長處,合作開發一種基于位元組碼的技術,到了 2015 年,“WebAssembly” 確定為正式名稱并對外公開,W3C 成立了 WASM 社區小組(成員包括Chrome、Edge、Firefox 和 WebKit),致力于推動 WASM 技術的發展,

2016 年 Rust 1.14發布,開始支持 WASM,
2017 年 Google 決定放棄 PNaCl 技術;四大瀏覽器 Chrome、Edge、Safari、Firefox 更新版本開始支持 WASM,
2018 年 Go 1.11 發布,開始支持 WASM,
2019 年 Emscripten 更新為默認使用 LLVM 編譯為 WASM 代碼,停止對 asm.js 的支持;WebAssembly 成為萬維網聯盟(W3C)的推薦標準,與 HTML,CSS 和 JavaScript 一起成為 Web 的第四種語言,

簡介

官方給出的定義:WebAssembly / WASM 是基于堆疊式虛擬機的二進制指令集,可以作為編程語言的編譯目標,能夠部署在 Web 客戶端和服務端的應用中,

WebAssembly 具有如下特性:

  • 是一種底層類匯編語言,能夠在所有當代桌面瀏覽器及很多移動瀏覽器上以接近本地的速度運行,
  • 檔案設計得很緊湊,因此可以快速傳輸和下載,這些檔案的設計方式也使得它們可以快速決議和初始化,
  • 被設計為編譯目標,讓 C++、Rust 和其他語言撰寫的代碼現在可以在 Web 上運行,

也就是說 WebAssembly 可以使得以各種語言撰寫的代碼都可以以接近原生的速度在瀏覽器中運行,

WebAssembly 也被設計為與 JavaScript 共存并協同作業,相對于 JavaScript(包括 asm.js)解決了如下幾個問題:

  • 性能提升,由于 WebAssembly是一種底層類匯編語言,代碼是靜態型別,瀏覽器執行時可以直接將其編譯成機器碼去大幅提高性能;并且由于 WebAssembly 是位元組碼形式,檔案體積也很小,便于網路快速傳輸,瀏覽器廠商甚至引入了“流編譯”技術,讓檔案可以邊下載邊編譯,下載完畢即可進行初始化,
  • 融合不同語言,之前想在 Web 上執行其他語言,只能把其他語言轉成 JavaScript 語言,但這個程序并不容易,而且會帶來執行性能上的大幅降低;而 WebAssembly 從設計之初就定位為編譯目標語言,讓其他語言可以輕松轉成 WebAssembly 語言代碼,不僅不用擔心性能(雖然仍會有一定損失),也讓代碼復用變得簡單,
  • 加強代碼安全,對 JavaScript 代碼進行保護通常只能使用混淆來大幅降低代碼可讀性,但是在一些工具的幫助下只要多花費一些時間仍然可讀,但是轉譯而來的 WASM 代碼則完全不具有可讀性,即使通過 wasm2c 等工具進行反編譯,依然比分析 JS 代碼要難度大很多(當然并不會達到完全的代碼安全,但增加逆向難度會使其風險大大降低),

不過 WebAssembly 并不是純瀏覽器平臺的技術,猶如 JavaScript 與 Node.js,如今它也有自己的 Runtime,在瀏覽器之外的云原生、區塊鏈、安全等系統應用領域都有諸多應用,

編譯

C / C++ 通過 Emscripten 編譯:

emcc hello.c -o hello.wasm

Rust 通過 Cargo 編譯:

cargo build --target wasm32-example --release

還可以進一步壓縮體積:

wasm-gc target/wasm32-example/release/hello.wasm

Golang 內置編譯:

GOARCH=wasm GOOS=js go build -o hello.wasm main.go

運行

在 JavaScript 運行

為了在 JavaScript 中運行 WebAssembly,在編譯/實體化之前,你首先需要把模塊放入記憶體,比如通過 XMLHttpRequest 或 Fetch,模塊將會被初始化為帶型別陣列,

使用 Fetch 的例子:

fetch('module.wasm').then(response =>
  response.arrayBuffer()
).then(bytes =>
  WebAssembly.instantiate(bytes, importObject)
).then(results => {
  result.instance.exports
});

上述方式是先創建一個包含你的 WebAssembly 模塊二進制代碼的 ArrayBuffer,然后使用 WebAssembly.instantiate() 編譯它,

你也可以使用 WebAssembly.instantiateStreaming(),該方法直接從原始位元組碼中直接獲取,編譯和實體化模塊,無需轉換為 ArrayBuffer:

WebAssembly.instantiateStreaming(fetch('simple.wasm'), importObject)
.then(result => {
  result.instance.exports
});

WebAssembly 計劃未來會支持 <script type='module'> 和 ES6 的 import 陳述句這種形式直接加載運行,

在瀏覽器之外運行

Wasm 社區提供了很多 Runtime 容器,讓 WASM 可以在瀏覽器之外的系統上執行,并且運行環境是沙箱化的,

目前比較流行的 Runtime:

  • wasmtime:既可以作為一個CLI,也可以被嵌入到其他應用系統中,如 IoT 或者云原生
  • WebAssembly Micro Runtime:更偏向于芯片場景的虛擬機,如它的名字所示,體積非常小,起步速度只要 100 微秒,記憶體耗費最低只需 100KB
  • wasmer:特點是支持在更多的編程語言運行 WASM 實體,并有自己的包管理平臺 Wapm
  • WasmEdge:之前名為 SSVM,對云原生、邊緣和去中心化應用有針對性優化

底層概念

模塊

WebAssembly 程式的主要單元稱為模塊(Module),這個術語既用來表示代碼的二進制版本,也表示瀏覽器中的編譯后版本,

一個大型 WebAssembly 應用往往由多個子模塊組成,每個模塊都擁有自己的獨立資料資源,因此子模塊無法篡改其他模塊的資料;另外每個模塊所能使用的權限由最上層的呼叫者指定,因此第三方子模塊無法在上層模塊不感知的情況下越權呼叫,這種權限管理類似于 Android 開發需要預先宣告所有依賴的權限一樣,

當其他高級語言編譯成 WebAssembly 后,會成為了一個模塊二進制檔案,檔案名是以 .wasm 后綴結尾,檔案內容開頭是 8 位元組的用于描述的模塊頭:

0000000: 0061 736d              ; WASM_BINARY_MAGIC
0000004: 0d00 0000              ; WASM_BINARY_VERSION

前4 位元組被稱為“魔數(Magic Number)”,對應 \0asm 字串,用來識別這是一個 Wasm 模塊;后 4 位元組是當前模塊所使用的 WASM 標準版本號,

在模塊頭之后就是模塊的主體內容,這些內容被分門別類放在不同的段(Section),Wasm 把特定功能或者有相關聯的代碼放進一個特定的段中,有些段是任何的模塊都必需的,有些段是可選的,

段可能會包含多個專案,Wasm 規范一共定義了 12 種段,并給每種段分配了 ID,除了自定義段以外,其他所有的段都最多只能出現一次,且必須按照段 ID 遞增的順序出現,

下面是各個段的說明,其中粗體是必需存在的段:

ID 說明
0 自定義段(Custom) 主要用于存盤除錯資訊等資料
1 型別段(Type) 存盤匯入函式、模塊內部函式的函式引數串列
2 匯入段(Import) 用于存盤匯入函式的函式名稱、函式引數索引
3 函式段(Function) 用于存盤函式索引值
4 表格段(Table) 用于存盤物件參考,通過表格段可以實作函式指標的功能(call_indirect 指令),可以從外部宿主匯入,同時也可以匯出到外部宿主環境
5 記憶體段(Memory) 用于存盤程式的運行時動態資料,可以從外部宿主匯入,同時也可以匯出到外部宿主環境
6 全域段(Global) 用于存盤全部變數值
7 匯出段(Export) 用于存盤匯出函式的函式名稱、函式引數索引
8 開始段(Start) 用于指定模塊初始化時的函式索引值
9 元素段(Elem) 表格段并沒有顯式地初始化,元素段用于存盤函式的索引值
10 代碼段(Code) 用于存盤函式的指令代碼
11 資料段(Data) 用于存盤初始化記憶體的靜態資料

資料型別

WASM 在二進制編碼里的資料型別如下:

  • 無符號整數,支持三種非負整數型別:uint8、uint16、uint32,后面的數字表示占用了多少個bit
  • 可變長無符號整數,支持三種可變長非負整數型別:varuint1、varuint7、varuint32,所謂可變長的意思是會根據具體資料大小決定使用多少bit,后面的數字表示最大可占用多少個bit
  • 可變長有符號整數,同上,這里允許負數的出現,支持varint7、varint32、varint64 三種型別
  • 浮點數,同 JavaScript,采用 IEEE-754 方案,單精度為32位

對于語言本身,提供以下數值型別:

  • i32: 32-bit 整型
  • i64: 64-bit 整型
  • f32: 32-bit 浮點型
  • f64: 64-bit 浮點型

每個引數和區域變數都必須是以上四種值型別之一 ,函式簽名由 0 或多個引數的型別序列及 0 或多個回傳值的型別序列組成,(在最小可行版本中,一個函式最多可以有一個回傳型別),需要注意的是,值型別 i32 和 i64 不是固有有符號或無符號的, 這些型別的解釋取決于某個具體的運算子,

布林值用無符號 32 位整數表示,0 為 false,非 0 值為 true,所有其他值型別(如字串)需要在模塊的線性記憶體空間中表示,

WAT

WASM 二進制檔案是不可讀的,WAT (WebAssembly Text Format) 是另外一種輸出格式,是使用 “S- 運算式” 的文本格式,可以近似理解為與二進制等價的匯編語言,

C、WAT、WASM 代碼轉換

部分瀏覽器的開發者工具支持將 WASM 轉換成 WAT 查看,便于在線除錯,社區提供了 wasm2watwat2wasm 等成熟的工具將二者進行轉換,可以在 WABT (WebAssembly Binary Toolkit) 工具集中找到,所以也是可以直接撰寫 WAT 再轉換成 WASM,

WASI

WebAssembly 雖然是為了 Web 而生,但并不意味著它只能也不打算只在瀏覽器上運行,開發人員想將它推向了瀏覽器之外,而這需要提供一套與作業系統互動的介面,

由于 WebAssembly 是基于概念機器的匯編語言,而不是物理機器,因此,WebAssembly提供了一種快速,可擴展,安全的方式來在所有計算機上運行相同的代碼,同時為了在所有不同的作業系統上運行,WebAssembly 需要一個概念機器的系統介面,而不是任何單個作業系統,于是開發人員定義了一種與不同作業系統通信統一標準,名為 WASI (WebAssembly System Interface),它是為 WASM 專門設計一套引擎無關(engine-indepent)、面向非 Web 系統(non-Web system-oriented)的 API 標準,

WASI 的設計遵循兩大原則:

  • 可移植性,能夠編譯可移植的二進制檔案,編譯一次就能在不同的計算機上運行,讓用戶分發代碼更容易,例如,Node 的原生模塊如果是用 WebAssembly 撰寫的,那么當用戶安裝帶有原生模塊的應用時就不需要運行 node-gyp 了,開發人員也無需配置并分發幾十個二進制檔案了,
  • 安全性,當一行代碼請求作業系統執行某些輸入或輸出時,作業系統需要確定該代碼所請求的操作是否安全,WebAssembly 采用了沙箱機制,代碼不能直接與作業系統互動,宿主機(可能是瀏覽器,也可能是 WASM 運行時)需要將相關函式放入代碼可以使用的沙箱中,宿主機可以逐一限制每個程式可以做什么,雖然擁有沙箱機制并不會使系統本身變安全(宿主機仍然可以將所有能力都放入到沙箱中),不過它至少讓宿主機能夠選擇創建更安全的系統,

基于上述兩項關鍵原則,WASI 被設計為一組模塊化的標準介面,其中最基礎的核心模塊為 wasi-core,其它的比如 sensorscryptoprocessesmultimedia 等子集合都是以單獨的子模塊的形式組織,

WASI 模塊

wasi-core 包含所有程式都需要的基本介面,它會覆寫與 POSIX 近乎相同的領域,包括諸如檔案、網路連接、時鐘以及亂數等相關系統呼叫的 WASI 抽象函式介面,

WASI 在 WASM 位元組碼與虛擬機之間,增加了一層“系統呼叫抽象層”,比如對于在 C/C++ 原始碼中使用的 fopen 函式,當我們將這部分源代碼與專為 WASI 實作的 C 標準庫 wasi-libc 進行編譯時,原始碼中對 fopen 的函式呼叫程序,其內部會間接通過呼叫名為 __wasi_path_open 的函式來實作,這個 __wasi_path_open 函式,便是對實際系統呼叫的一個抽象,

WASI 主要作業是定義 Import 介面標準,提供通用 Import 介面在不同系統上的具體實作(與不同作業系統上實作libc模式類似), 基于 WASI 的設計思路,針對不同的領域我們還可以提供更上層的WADSI(WebAssembly Domain Specific Interface),將領域通用的介面作為 Import 介面提供,從而使得開發者可以直接使用,

安全性

WebAssembly 的安全性來源之一是,它是第一個共享 JavaScript VM 的語言,而 JavaScript VM 在運行時是沙箱化的,同時也經歷了多年的檢驗和安全測驗,這確保了其安全性,WebAssembly 模塊的可訪問范圍不超過 JavaScript 的訪問范圍,同時也會遵守相同的安全性規則,包括同源策略(same-origin policy)這樣的增強規則,

與桌面應用程式不同,WebAssembly 模塊對設備記憶體沒有直接訪問權限,而是運行時環境在初始化程序中向模塊傳遞一個 ArrayBuffer ,模塊將這個 ArrayBuffer 當作線性記憶體來使用,WebAssembly 框架執行檢查以確保代碼不會對這個陣列進行越界操作,

對于像函式指標這樣存盤在 Table 段中的專案,WebAssembly 模塊也不能直接訪問,代碼會用索引值向WebAssembly框架提出訪問某個專案的請求,然后框架訪問記憶體,并代表代碼執行這個專案,

在 C++ 中,執行堆疊與線性記憶體一起位于記憶體中,雖然 C++ 代碼不應該修改執行堆疊,但是它可以使用指標實作修改,WebAssembly的執行堆疊與線性記憶體是分離的,代碼無法訪問,

應用案例

谷歌地球
谷歌地球在 2017 年發布是 9.0 版本中,采用的是 NaCl 技術開發,所以當時只能在 Chrome 上運行,2020 年谷歌使用 C++ 通過 WebAssembly 重寫了該專案,從此可以在 Firefox 和 Edge 上運行,

谷歌地球

AutoCAD
AutoCAD 是一款由將近 40 年歷史的知名桌面端設計軟體,被廣泛地用于土木建筑、裝飾裝潢、工業制圖等多個領域中,2014 年 AutoCAD 發布 Web 版,是通過 Google Web Toolkit(一個 Google 開發的可以使用 Java 語言開發 Web 應用的工具集)的幫助下開發,將 Android 端的 Java 代碼轉譯成 JS 代碼,但由于生成的 JS 代碼十分龐大,導致瀏覽器上運行效率很低,2015 年又通過 asm.js 將原有的 C++ 代碼中的主要功能直接進行編譯移植到到 Web 平臺,性能有了很大的提告,2018 年 3 月,基于 WASM 構建的 AutoCAD Web 也成功誕生,

AutoCAD

Figma
Figma 是一個基于瀏覽器的協作式 UI 設計工具,核心的互動界面是在一個 Canvas 內承載,這個 Canvas 的互動是通過 WASM 控制的,基于瀏覽器讓它可以輕松跨平臺運行,而 WebAssembly 帶來了高性能,讓它即使在 Web 平臺依然在速度上完勝那些基于原生 OS 開發的同類應用,

Figma

結語

可以看出 WebAssembly 并不是用來完全取代 JavaScript,而是作為 Web 技術的補充,在性能和代碼復用等方面彌補 JavaScript 的局限,正如 WASM 官方的口號:“所有可以用 WebAssembly 實作的終將會用 WebAssembly 實作”,WebAssembly 的最終目標是用任何語言編譯而來并可以高效運行在任何平臺,最重要的是它背靠 Google、Mozilla、Edge 等主流開發機構的支持,相信在未來一定還會有更長足的發展,

參考資料

  • WebAssembly原理與核心技術
  • WebAssembly實戰
  • 標準化中的 WASI:在 web 之外運行 WebAssembly 的系統介面
  • 創建并使用 WebAssembly 模塊
  • WebAssembly | MDN

轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/433306.html

標籤:JavaScript

上一篇:分析HTTP請求以降低HTTP走私攻擊HTTP資料接收不同步攻擊的風險

下一篇:three.js的使用

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • IEEE1588PTP在數字化變電站時鐘同步方面的應用

    IEEE1588ptp在數字化變電站時鐘同步方面的應用 京準電子科技官微——ahjzsz 一、電力系統時間同步基本概況 隨著對IEC 61850標準研究的不斷深入,國內外學者提出基于IEC61850通信標準體系建設數字化變電站的發展思路。數字化變電站與常規變電站的顯著區別在于程序層傳統的電流/電壓互 ......

    uj5u.com 2020-09-10 03:51:52 more
  • HTTP request smuggling CL.TE

    CL.TE 簡介 前端通過Content-Length處理請求,通過反向代理或者負載均衡將請求轉發到后端,后端Transfer-Encoding優先級較高,以TE處理請求造成安全問題。 檢測 發送如下資料包 POST / HTTP/1.1 Host: ac391f7e1e9af821806e890 ......

    uj5u.com 2020-09-10 03:52:11 more
  • 網路滲透資料大全單——漏洞庫篇

    網路滲透資料大全單——漏洞庫篇漏洞庫 NVD ——美國國家漏洞庫 →http://nvd.nist.gov/。 CERT ——美國國家應急回應中心 →https://www.us-cert.gov/ OSVDB ——開源漏洞庫 →http://osvdb.org Bugtraq ——賽門鐵克 →ht ......

    uj5u.com 2020-09-10 03:52:15 more
  • 京準講述NTP時鐘服務器應用及原理

    京準講述NTP時鐘服務器應用及原理京準講述NTP時鐘服務器應用及原理 安徽京準電子科技官微——ahjzsz 北斗授時原理 授時是指接識訓通過某種方式獲得本地時間與北斗標準時間的鐘差,然后調整本地時鐘使時差控制在一定的精度范圍內。 衛星導航系統通常由三部分組成:導航授時衛星、地面檢測校正維護系統和用戶 ......

    uj5u.com 2020-09-10 03:52:25 more
  • 利用北斗衛星系統設計NTP網路時間服務器

    利用北斗衛星系統設計NTP網路時間服務器 利用北斗衛星系統設計NTP網路時間服務器 安徽京準電子科技官微——ahjzsz 概述 NTP網路時間服務器是一款支持NTP和SNTP網路時間同步協議,高精度、大容量、高品質的高科技時鐘產品。 NTP網路時間服務器設備采用冗余架構設計,高精度時鐘直接來源于北斗 ......

    uj5u.com 2020-09-10 03:52:35 more
  • 詳細解讀電力系統各種對時方式

    詳細解讀電力系統各種對時方式 詳細解讀電力系統各種對時方式 安徽京準電子科技官微——ahjzsz,更多資料請添加VX 衛星同步時鐘是我京準公司開發研制的應用衛星授時時技術的標準時間顯示和發送的裝置,該裝置以M國全球定位系統(GLOBAL POSITIONING SYSTEM,縮寫為GPS)或者我國北 ......

    uj5u.com 2020-09-10 03:52:45 more
  • 如何保證外包團隊接入企業內網安全

    不管企業規模的大小,只要企業想省錢,那么企業的某些服務就一定會采用外包的形式,然而看似美好又經濟的策略,其實也有不好的一面。下面我通過安全的角度來聊聊使用外包團的安全隱患問題。 先看看什么服務會使用外包的,最常見的就是話務/客服這種需要大量重復性、無技術性的服務,或者是一些銷售外包、特殊的職能外包等 ......

    uj5u.com 2020-09-10 03:52:57 more
  • PHP漏洞之【整型數字型SQL注入】

    0x01 什么是SQL注入 SQL是一種注入攻擊,通過前端帶入后端資料庫進行惡意的SQL陳述句查詢。 0x02 SQL整型注入原理 SQL注入一般發生在動態網站URL地址里,當然也會發生在其它地發,如登錄框等等也會存在注入,只要是和資料庫打交道的地方都有可能存在。 如這里http://192.168. ......

    uj5u.com 2020-09-10 03:55:40 more
  • [GXYCTF2019]禁止套娃

    git泄露獲取原始碼 使用GET傳參,引數為exp 經過三層過濾執行 第一層過濾偽協議,第二層過濾帶引數的函式,第三層過濾一些函式 preg_replace('/[a-z,_]+\((?R)?\)/', NULL, $_GET['exp'] (?R)參考當前正則運算式,相當于匹配函式里的引數 因此傳遞 ......

    uj5u.com 2020-09-10 03:56:07 more
  • 等保2.0實施流程

    流程 結論 ......

    uj5u.com 2020-09-10 03:56:16 more
最新发布
  • 使用Django Rest framework搭建Blog

    在前面的Blog例子中我們使用的是GraphQL, 雖然GraphQL的使用處于上升趨勢,但是Rest API還是使用的更廣泛一些. 所以還是決定回到傳統的rest api framework上來, Django rest framework的官網上給了一個很好用的QuickStart, 我參考Qu ......

    uj5u.com 2023-04-20 08:17:54 more
  • 記錄-new Date() 我忍你很久了!

    這里給大家分享我在網上總結出來的一些知識,希望對大家有所幫助 大家平時在開發的時候有沒被new Date()折磨過?就是它的諸多怪異的設定讓你每每用的時候,都可能不小心踩坑。造成程式意外出錯,卻一下子找不到問題出處,那叫一個煩透了…… 下面,我就列舉它的“四宗罪”及應用思考 可惡的四宗罪 1. Sa ......

    uj5u.com 2023-04-20 08:17:47 more
  • 使用Vue.js實作文字跑馬燈效果

    實作文字跑馬燈效果,首先用到 substring()截取 和 setInterval計時器 clearInterval()清除計時器 效果如下: 實作代碼如下: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta ......

    uj5u.com 2023-04-20 08:12:31 more
  • JavaScript 運算子

    JavaScript 運算子/運算子 在 JavaScript 中,有一些運算子可以使代碼更簡潔、易讀和高效。以下是一些常見的運算子: 1、可選鏈運算子(optional chaining operator) ?.是可選鏈運算子(optional chaining operator)。?. 可選鏈操 ......

    uj5u.com 2023-04-20 08:02:25 more
  • CSS—相對單位rem

    一、概述 rem是一個相對長度單位,它的單位長度取決于根標簽html的字體尺寸。rem即root em的意思,中文翻譯為根em。瀏覽器的文本尺寸一般默認為16px,即默認情況下: 1rem = 16px rem布局原理:根據CSS媒體查詢功能,更改根標簽的字體尺寸,實作rem單位隨螢屏尺寸的變化,如 ......

    uj5u.com 2023-04-20 08:02:21 more
  • 我的第一個NPM包:panghu-planebattle-esm(胖虎飛機大戰)使用說明

    好家伙,我的包終于開發完啦 歡迎使用胖虎的飛機大戰包!! 為你的主頁添加色彩 這是一個有趣的網頁小游戲包,使用canvas和js開發 使用ES6模塊化開發 效果圖如下: (覺得圖片太sb的可以自己改) 代碼已開源!! Git: https://gitee.com/tang-and-han-dynas ......

    uj5u.com 2023-04-20 08:01:50 more
  • 如何在 vue3 中使用 jsx/tsx?

    我們都知道,通常情況下我們使用 vue 大多都是用的 SFC(Signle File Component)單檔案組件模式,即一個組件就是一個檔案,但其實 Vue 也是支持使用 JSX 來撰寫組件的。這里不討論 SFC 和 JSX 的好壞,這個仁者見仁智者見智。本篇文章旨在帶領大家快速了解和使用 Vu ......

    uj5u.com 2023-04-20 08:01:37 more
  • 【Vue2.x原始碼系列06】計算屬性computed原理

    本章目標:計算屬性是如何實作的?計算屬性快取原理以及洋蔥模型的應用?在初始化Vue實體時,我們會給每個計算屬性都創建一個對應watcher,我們稱之為計算屬性watcher ......

    uj5u.com 2023-04-20 08:01:31 more
  • http1.1與http2.0

    一、http是什么 通俗來講,http就是計算機通過網路進行通信的規則,是一個基于請求與回應,無狀態的,應用層協議。常用于TCP/IP協議傳輸資料。目前任何終端之間任何一種通信方式都必須按Http協議進行,否則無法連接。tcp(三次握手,四次揮手)。 請求與回應:客戶端請求、服務端回應資料。 無狀態 ......

    uj5u.com 2023-04-20 08:01:10 more
  • http1.1與http2.0

    一、http是什么 通俗來講,http就是計算機通過網路進行通信的規則,是一個基于請求與回應,無狀態的,應用層協議。常用于TCP/IP協議傳輸資料。目前任何終端之間任何一種通信方式都必須按Http協議進行,否則無法連接。tcp(三次握手,四次揮手)。 請求與回應:客戶端請求、服務端回應資料。 無狀態 ......

    uj5u.com 2023-04-20 08:00:32 more