主頁 > 前端設計 > ?探秘 Web 水印技術

?探秘 Web 水印技術

2022-09-14 06:49:39 前端設計

 

 

Web 水印技術在資訊安全和著作權保護等領域有著廣泛的應用,對防止資訊泄露或知識產品被侵犯有重要意義,水印根據可見性可分為可見水印和不可見水印(盲水印),本文將分別予以介紹,帶你探秘 web 水印技術,

可見水印

最簡單的水印

一種比較常見的簡單水印場景是給文章、表格加上 logo 水印,用以申明著作權,

 

 這里想要的效果就是一個淺淺的 logo 平鋪展示,實作起來也比較簡單,只需制作一個半透明的 logo 圖片,設為文章或者表格的背景圖片即可,僅需一行 CSS 宣告,

background-image:url("./logo.png");

實作圖片平鋪關鍵的 CSS 屬性是 background-repeat,值為 repeat 時是平鋪,這也是它的默認值,所以可以省略,

全頁面水印

照葫蘆畫瓢,如果要給整個 Web 頁面加上水印,是不是給頁面的 body 元素設定背景圖片平鋪展示就可以了呢?

然而通常并不會這么處理,因為文章和表格內容多以文本為主,不會明顯遮擋水印,而一個完整的頁面往往還包含很多其他頁面元素,比如圖片、視頻、控制元件等等,它們很可能會遮擋住背景圖片,從而影響水印效果,

所以,為了避免被其他元素遮擋,針對頁面的水印一般會使用一個層級比較高且覆寫整個頁面的元素來承載,

div.watermark{
  position: fixed;
  left:0;
  top:0;
  width: 100vw;
  height: 100vh;
  background-image:url("./logo.png");
  opacity: .5;
  z-index: 3000;
}

這樣一來,其他元素就遮擋不住水印了,不過,這個 div 反過來可能會遮擋頁面其他元素,影響頁面元素操作,還需要一條關鍵的 CSS 宣告來破解這個問題 :

pointer-events: none;

這個 CSS 宣告會使該元素“可穿透”,“看得見、摸不著”,不再影響頁面操作,

動態水印

很多時候,給頁面加水印的目的并不是申明著作權,而是為了支持溯源,此時水印的內容并不會只是一個 logo,通常會包含用戶資訊,比如用戶名、UID、手機號等等,

 

 

這就意味著,每個用戶的水印內容是不同的,無法通過提前準備好一張圖片來滿足了,這種場景往往需要根據用戶資訊動態生成圖片,

我們來看下幾種主流的動態生成水印圖片的方式:

服務端方案

傳統的方式是在服務端生成圖片,頁面上發起的圖片請求中可以附帶用戶資訊,服務端根據這些引數動態生成圖片,并將圖片資料作為該請求的回應返給頁面,頁面拿到后將其用作水印,

這種方式的優點是兼容性好,缺點是需要前后端配合,增加了頁面請求和服務端資源開銷,防攻擊能力也較差,

Canvas 方案

HTML5 引入 Canvas 特性使得瀏覽器自身具備了繪圖能力,經過多年的發展,主流瀏覽器基本都已可以提供良好的支持,通過 Canvas 可以輕松繪制圖片,并可將圖片資料匯出,用于頁面圖片或背景,

const canvasElement = document.createElement('canvas');
const context = canvasElement.getContext('2d');
canvasElement.width = 200;
canvasElement.height = 200;
context.rotate((-30 * Math.PI) / 180);
context.font = '400 26px Arial';
context.fillStyle = '#B9C0CA';
context.textAlign = 'center';
context.textBaseline = 'middle';
context.fillText('水印文字', 70, 130);
const watermark = canvasElement.toDataURL('image/png');

通過上述示例代碼可拿到水印圖片的 data URI 資料,用作水印承載元素的背景圖片平鋪展示即可,

這種方式不需要服務端配合,在前端就可以完成,且有助于減少請求和服務端資源開銷,曾經面臨的瀏覽器兼容問題現在也不再是問題,該方案已逐漸流行起來,

SVG 方案

對于純文字的水印來說,有沒有辦法不生成圖片而直接實作平鋪呢?

動態創建大量 DOM 節點,通過 CSS 控制排列當然可以實作,但是繁瑣且性能差,優雅更無從談起,

不妨換個角度思考,有沒有辦法讓文字不轉成圖片就可以用作 background-image 屬性的值呢?這樣就可以利用 background-repeat 實作平鋪效果了,

這時候可以考慮使用 SVG,因為 SVG 具有文本和影像的雙重特性,看上去是文本,然而在很多場景可以當做圖片使用,

我們可以通過 SVG 的相關屬性精準控制字體位置、大小、顏色、透明度和旋轉角度等引數,如:

<svg width="200" height="200" xmlns="http://www.w3.org/2000/svg">
  <text x="50%" y="50%" font-size="30" fill="#a2a9b6" fill-opacity="0.3" font-family="system-ui, sans-serif" text-anchor="middle" dominant-baseline="middle" transform='rotate(-45, 100 100)'>水印文字</text>
</svg>

考慮到瀏覽器兼容性,用作背景圖片時,建議將 SVG 編碼為 Base64(或轉義特定字符):

 

background-image: url("data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjAwIiBoZWlnaHQ9IjIwMCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48dGV4dCB4PSI1MCUiIHk9IjUwJSIgZm9udC1zaXplPSIzMCIgZmlsbD0iI2EyYTliNiIgZmlsbC1vcGFjaXR5PSIwLjMiIGZvbnQtZmFtaWx5PSJzeXN0ZW0tdWksIHNhbnMtc2VyaWYiIHRleHQtYW5jaG9yPSJtaWRkbGUiIGRvbWluYW50LWJhc2VsaW5lPSJtaWRkbGUiIHRyYW5zZm9ybT0ncm90YXRlKC00NSwgMTAwIDEwMCknPuawtOWNsOaWh+WtlzwvdGV4dD48L3N2Zz4=");

 

 

水印安全

水印是用來保護資訊安全的,資訊要安全,首先要確保水印自身的安全,提高水印的防攻擊(篡改、洗掉等)能力,

可見水印大都是基于 DOM 的,找到這個 DOM 節點,通過瀏覽器插件、抓包工具等在頁面上注入一段 JavaScript 或者 CSS 代碼對其進行篡改或洗掉并不困難,

防止外部代碼篡改,一種思路是把水印元素封裝起來,與外部環境進行隔離,

Shadow DOM

在 Chrome 逐步統治瀏覽器江湖之后,谷歌正野心勃勃的推廣 Web Components 技術,該技術允許在 Web 中創建可重用的小部件或組件,組件化開發在前端業界已經流行相當長一段時間了,這主要得益于前端三大框架的推崇,但具體組件標準是由框架各自制定的,而 Web Components 可理解為 Web 標準化的組件,

Web Components 的一個重要特性就是“封裝”,即可以將標記結構、樣式和行為隱藏起來,并與頁面上的其他代碼相隔離,比如我們熟悉的 video 元素,它的進度條、按鈕等控制元件都已被封裝,

 

 Shadow DOM 介面是“封裝”特性的關鍵所在,它可以將一個隱藏的、獨立的 DOM 附加到一個元素上,

 

 

為了提高 web 水印的隱蔽性,同時避免受外部代碼影響,從而在一定程度上防止篡改,可以考慮把水印元素放在 Shadow DOM 中,

來看下 Shadow DOM 的基本用法,使用 Element.attachShadow() 方法來將一個 shadow root 附加到任何一個元素上,它接受一個配置物件作為引數,該物件有一個 mode 屬性,值可以是 open 或者 closed ,open 表示可以通過頁面內的 JavaScript 方法來獲取 Shadow DOM,而 closed 則表示不可以從外部獲取 Shadow DOM ,

Element.attachShadow({mode: 'closed'});

 

 

樣式怎么隔離呢?Shadow DOM 中的樣式本身就是隔離的,除非主動使用 CSS 變數、part 屬性等暴露,外部樣式是不會影響到組件內的,

Mutation Observer

Shadow DOM 提高了水印的隱蔽性,同時可以防止外部代碼修改,除此之外,還有一種常見的攻擊場景——人為修改,比如在瀏覽器控制臺直接修改或洗掉對應的 DOM 元素,

 

可以考慮“監聽”這種行為,一旦發生就馬上修復,比如重新插入一個,那怎么實作這種“監聽”呢?現代瀏覽器中有多種觀察者(Observer),比如IntersectionObserverPerformanceObserverResizeObserverReportingObserverMutationObserver 等,其中,MutationObserver 就可以用來監聽 DOM 變動,DOM 的任何變動,比如節點的增減、屬性的變動、文本內容的變動,通過該 API 都可以得到通知,

所以可以使用 MutationObserver API 來監聽水印元素 DOM 變化,一旦監聽到 DOM 元素被修改或者洗掉,就立即重新插入一個,

 

 

不可見水印(盲水印)

不可見水印也叫盲水印、隱水印,顧名思義是一種看不到的水印,看不到還要它做什么呢?其實,不可見水印在一些對安全性要求較高的場景意義還是蠻大的,不可見水印通常具有比可見水印更好的隱蔽性和抗攻擊性,雖不可見,但通過一定的技術手段是可以將水印資訊從其載體上提取出來的,這就使得其載體具備了溯源能力,在關鍵時刻往往能發揮大作用,

我總結不可見水印相對可見水印至少有以下三個明顯的優勢:

  • 更好的觀感,可見水印總給人一種“膏藥感”,甚至會引起部分人的不適,而不可見水印則不會有這個問題,
  • 更佳的隱蔽性,用戶基本感知不到水印的存在,
  • 更強的抗攻擊性,可見水印更容易受到攻擊,而不可見水印除了隱蔽性比較強之外,其自身往往還具備比較強的抗攻擊能力,

不可見水印(盲水印)屬于資訊隱匿技術(也叫隱寫術),歷史悠久,手段繁多,在現代,隨著計算機網路技術的發展,數字產品的資訊安全和著作權保護也已成為資訊隱匿技術的一個重要課題,隱寫術在數字音頻、數字視頻和數字影像領域有著非常廣泛的應用,

Web 上基于 DOM 的盲水印大都不靠譜,而另一方面數字影像是資訊隱藏和數字水印領域研究最多和最早的一種載體,相較于 Web,數字影像領域有著更為成熟的數字水印演算法,我們不妨先來看下數字影像領域的常見盲水印技術,

在說數字水印之前,這里介紹一些數字影像的基礎知識,

數字影像(位圖)是由像素(pixel)組成,

  • 非黑即白的二值影像,1 個 bit 即可表示 1 個像素(黑白兩種狀態),所以 1 個位元組(byte)可以表示 8 個像素,
  • 灰度圖,1 個像素有 256 種狀態(2 的 8 次方),需要 8 個 bit,即 1 個位元組,
  • 彩色的 RGB 圖,有 R / G / B 三個通道,每個通道 256 種狀態,使用 1 個位元組表示,共需 3 個位元組表示 1 個像素,
  • RGBA 圖,在 R / G / B 三個通道基礎上增加了一個透明度通道,256 種狀態,額外需要 1 個位元組,共需要 4 個位元組表示一個像素,

通常,考慮到計算速度和性能,影像處理和影像識別大都會將影像轉成灰度圖或者選擇其中一個通道進行,

LSB 水印

如上文所述,灰度影像的一個像素有 256 種狀態,通常用灰度值( 0-255 )表示,0 表示黑色,255 表示白色,灰度值越大表示亮度越高,

灰度可用一個位元組,即 8 位元二進制數表示,其中最高位對影像的貢獻最大,最低位對影像的貢獻最小,稱為最低位元位(Least Significant BitLSB),

如果將一個影像所有像素的位元位抽出來,就構成了 8 個不同的位平面,從 LSB(最低有效位 0)到 MSB(最高有效位 7),位平面從低位到高位,影像的特征逐漸變得復雜,細節不斷增加,相鄰位元的相關性也越強,而位元位越低包含的影像資訊就越少,最低位平面類似于隨機噪聲,因此,改變低位對影像的成像質量影響不大,

LSB 水印就是利用了這一點,用水印資訊替換載體影像的最低位元位,這樣原影像的 7 個高位平面就與表示水印資訊的最低位平面組成了新的影像,

 

 

 

LSB 水印魯棒性(防攻擊性)較差,水印資訊容易被抹去,

頻域水印

將數字影像用一個矩陣來表示,是影像的空間域表示方法,LSB 就是在影像的空間域隱藏資訊,魯棒性較差,而在影像信號的頻域(變換域)中隱藏資訊要比在空間域中隱藏資訊具有更好的魯棒性,那么如何把影像信號從空間域轉換到頻域呢?這里就需要用到大名鼎鼎的 傅里葉變換 了,

法國數學家傅里葉大家一定不陌生,高數里就有傅里葉級數,

 

 傅里葉提出的傅里葉變換(Fourier transform)理論,表示能將滿足一定條件的某個函式表示成三角函式(正弦和/或余弦函式)或者它們的積分的線性組合,可用于把信號從時間域(或空間域)變換到頻率域,

在此之前人們對信號的分析主要集中在空間域,傅里葉變換的提出為頻域分析奠定了基礎,有助于解決許多影像的問題,

 

 

傅里葉變換在數字影像處理領域有著極為重要的應用,影像領域變換的實質是把影像函式展開成具有不同空間頻率的正、余弦信號的疊加,也就是說任何影像都可以分解為若干個頻率不同的亮度呈正弦變化的影像之和,把影像從空間域變換到頻率域后,就能夠實作對影像資料進行不同頻率成分的提取,對于影像信號來說,可以把灰度(亮度)看做頻率,傅里葉變換可作為影像灰度值形成的空間域與其頻率域的橋梁,

在頻域中隱藏資訊就是傅里葉變換在數字影像處理領域的一個典型應用場景,通常多選擇在影像頻域的中頻部分嵌入資訊,因為高頻部分易于被各種信號處理方法破壞,而人的視覺又對低頻部分比較敏感,容易察覺低頻部分的變化,

在影像頻域嵌入水印資訊的大致流程為:把原始影像通過離散傅里葉變換轉換到頻域(變換域),把水印文字資訊混入,再經過離散傅里葉變換的逆變換,便得到了載有水印資訊的影像,水印資訊隱匿性較好,

 

 

光說不練假把式,操練起來,

下圖是我隨手拍的鵝廠北京總部大樓一角,

 

 對上圖的一個通道進行離散傅里葉變換,在其變換域(頻域)加入水印文字(fransli)后,再進行離散傅里葉變換的逆變換,便得到了下圖,怎么樣,看不到水印資訊吧?

對上圖進行離散傅里葉變換,將圖片轉換到頻域(變換域),我們可以清楚的看到嵌入的水印文字(下圖),

  

頻域盲水印具有比較好的防攻擊性,我們來測驗一下,

我們截取影像中的一部分并重新采樣,然后嘗試提取水印資訊,

可以看到還是有很大概率可以提取到有效水印資訊的,

 

 

 

Web 中的數字水印應用

上面介紹了幾種常見的不可見水印(盲水印)實作方式,其中魯棒性比較好的是基于頻域的數字影像盲水印,但這種水印主要是針對數字影像,而 Web 上的內容載體并不一定都是圖片,常見的需要加水印的載體除了圖片還有文本、表格等,這些場景該如何應用頻域盲水印呢?

或許,Canvas 就是答案,

Reference

  • Web Components
  • shadow DOM
  • 如何讓文字作為 CSS 背景圖片顯示?
  • 《數字影像隱寫分析》
  • 《數字影像處理原理與實踐》
  • 《資料隱藏技術揭秘》

 

作者:fransli

本文來自博客園,作者:古道輕風,轉載請注明原文鏈接:https://www.cnblogs.com/88223100/p/Exploring-Web-Watermarking-Technology.html

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

標籤:HTML5

上一篇:vue3+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)

熱門瀏覽
  • vue移動端上拉加載

    可能做得過于簡單或者比較low,請各位大佬留情,一起探討技術 ......

    uj5u.com 2020-09-10 04:38:07 more
  • 優美網站首頁,頂部多層導航

    一個個人用的瀏覽器首頁,可以把一下常用的網站放在這里,平常打開會比較方便。 第一步,HTML代碼 <script src=https://www.cnblogs.com/szharf/p/"js/jquery-3.4.1.min.js"></script> <div id="navigate"> <ul> <li class="labels labels_1"> ......

    uj5u.com 2020-09-10 04:38:47 more
  • 頁面為要加<!DOCTYPE html>

    最近因為寫一個js函式,需要用到$(window).height(); 由于手寫demo的時候,過于自信,其實對前端方面的認識也不夠體系,用文本檔案直接敲出來的html代碼,第一行沒有加上<!DOCTYPE html> 導致了$(window).height();的結果直接是整個document的高 ......

    uj5u.com 2020-09-10 04:38:52 more
  • WordPress網站程式手動升級要做好資料備份

    WordPress博客網站程式在進行升級前,必須要做好網站資料的備份,這個問題良家佐言是遇見過的;在剛開始接觸WordPress博客程式的時候,因為升級問題和博客網站的修改的一些嘗試,良家佐言是吃盡了苦頭。因為購買的是西部數碼的空間和域名,每當佐言把自己的WordPress博客網站搞到一塌糊涂的時候 ......

    uj5u.com 2020-09-10 04:39:30 more
  • WordPress程式不能升級為5.4.2版本的原因

    WordPress是一款個人博客系統,受到英文博客愛好者和中文博客愛好者的追捧,并逐步演化成一款內容管理系統軟體;它是使用PHP語言和MySQL資料庫開發的,用戶可以在支持PHP和MySQL資料庫的服務器上使用自己的博客。每一次WordPress程式的更新,就會牽動無數WordPress愛好者的心, ......

    uj5u.com 2020-09-10 04:39:49 more
  • 使用CSS3的偽元素進行首字母下沉和首行改變樣式

    網頁中常見的一種效果,首字改變樣式或者首行改變樣式,效果如下圖。 代碼: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, ......

    uj5u.com 2020-09-10 04:40:09 more
  • 關于a標簽的講解

    什么是a標簽? <a> 標簽定義超鏈接,用于從一個頁面鏈接到另一個頁面。 <a> 元素最重要的屬性是 href 屬性,它指定鏈接的目標。 a標簽的語法格式:<a href=https://www.cnblogs.com/summerxbc/p/"指定要跳轉的目標界面的鏈接">需要展示給用戶看見的內容</a> a標簽 在所有瀏覽器中,鏈接的默認外觀如下: 未被訪問的鏈接帶 ......

    uj5u.com 2020-09-10 04:40:11 more
  • 前端輪播圖

    在需要輪播的頁面是引入swiper.min.js和swiper.min.css swiper.min.js地址: 鏈接:https://pan.baidu.com/s/15Uh516YHa4CV3X-RyjEIWw 提取碼:4aks swiper.min.css地址 鏈接:https://pan.b ......

    uj5u.com 2020-09-10 04:40:13 more
  • 如何設定html中的背景圖片(全屏顯示,且不拉伸)

    1 <style>2 body{background-image:url(https://uploadbeta.com/api/pictures/random/?key=BingEverydayWallpaperPicture); 3 background-size:cover;background ......

    uj5u.com 2020-09-10 04:40:16 more
  • Java學習——HTML詳解(上)

    HTML詳解 初識HTML Hyper Text Markup Language(超文本標記語言) 1 <!--DOCTYPE:告訴瀏覽器我們要使用什么規范--> 2 <!DOCTYPE html> 3 <html lang="en"> 4 <head> 5 <!--meta 描述性的標簽,描述一些 ......

    uj5u.com 2020-09-10 04:40:33 more
最新发布
  • 我的第一個NPM包:panghu-planebattle-esm(胖虎飛機大戰)使用說明

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

    uj5u.com 2023-04-20 07:59:23 more
  • 生產事故-走近科學之消失的JWT

    入職多年,面對生產環境,盡管都是小心翼翼,慎之又慎,還是難免捅出簍子。輕則滿頭大汗,面紅耳赤。重則系統停擺,損失資金。每一個生產事故的背后,都是寶貴的經驗和教訓,都是專案成員的血淚史。為了更好地防范和遏制今后的各類事故,特開此專題,長期更新和記錄大大小小的各類事故。有些是親身經歷,有些是經人耳傳口授 ......

    uj5u.com 2023-04-18 07:55:04 more
  • 記錄--Canvas實作打飛字游戲

    這里給大家分享我在網上總結出來的一些知識,希望對大家有所幫助 打開游戲界面,看到一個畫面簡潔、卻又富有挑戰性的游戲。螢屏上,有一個白色的矩形框,里面不斷下落著各種單詞,而我需要迅速地輸入這些單詞。如果我輸入的單詞與螢屏上的單詞匹配,那么我就可以獲得得分;如果我輸入的單詞錯誤或者時間過長,那么我就會輸 ......

    uj5u.com 2023-04-04 08:35:30 more
  • 了解 HTTP 看這一篇就夠

    在學習網路之前,了解它的歷史能夠幫助我們明白為何它會發展為如今這個樣子,引發探究網路的興趣。下面的這張圖片就展示了“互聯網”誕生至今的發展歷程。 ......

    uj5u.com 2023-03-16 11:00:15 more
  • 藍牙-低功耗中心設備

    //11.開啟藍牙配接器 openBluetoothAdapter //21.開始搜索藍牙設備 startBluetoothDevicesDiscovery //31.開啟監聽搜索藍牙設備 onBluetoothDeviceFound //30.停止監聽搜索藍牙設備 offBluetoothDevi ......

    uj5u.com 2023-03-15 09:06:45 more
  • canvas畫板(滑鼠和觸摸)

    <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>canves</title> <style> #canvas { cursor:url(../images/pen.png),crosshair; } #canvasdiv{ bo ......

    uj5u.com 2023-02-15 08:56:31 more
  • 手機端H5 實作自定義拍照界面

    手機端 H5 實作自定義拍照界面也可以使用 MediaDevices API 和 <video> 標簽來實作,和在桌面端做法基本一致。 首先,使用 MediaDevices.getUserMedia() 方法獲取攝像頭媒體流,并將其傳遞給 <video> 標簽進行渲染。 接著,使用 HTML 的 < ......

    uj5u.com 2023-01-12 07:58:22 more
  • 記錄--短視頻滑動播放在 H5 下的實作

    這里給大家分享我在網上總結出來的一些知識,希望對大家有所幫助 短視頻已經無數不在了,但是主體還是使用 app 來承載的。本文講述 H5 如何實作 app 的視頻滑動體驗。 無聲勝有聲,一圖頂百辯,且看下圖: 網址鏈接(需在微信或者手Q中瀏覽) 從上圖可以看到,我們主要實作的功能也是本文要講解的有: ......

    uj5u.com 2023-01-04 07:29:05 more
  • 一文讀懂 HTTP/1 HTTP/2 HTTP/3

    從 1989 年萬維網(www)誕生,HTTP(HyperText Transfer Protocol)經歷了眾多版本迭代,WebSocket 也在期間萌芽。1991 年 HTTP0.9 被發明。1996 年出現了 HTTP1.0。2015 年 HTTP2 正式發布。2020 年 HTTP3 或能正... ......

    uj5u.com 2022-12-24 06:56:02 more
  • 【HTML基礎篇002】HTML之form表單超詳解

    ??一、form表單是什么

    ??二、form表單的屬性

    ??三、input中的各種Type屬性值

    ??四、標簽 ......

    uj5u.com 2022-12-18 07:17:06 more