很全很全的前端本地存儲講解

来源:https://www.cnblogs.com/qianduantuanzhang/archive/2018/01/04/8193892.html
-Advertisement-
Play Games

三種本地存儲方式 cookie 前言 網路早期最大的問題之一是如何管理狀態。簡而言之,伺服器無法知道兩個請求是否來自同一個瀏覽器。當時最簡單的方法是在請求時,在頁面中插入一些參數,併在下一個請求中傳回參數。這需要使用包含參數的隱藏的表單,或者作為URL參數的一部分傳遞。這兩個解決方案都手動操作,容易 ...


三種本地存儲方式

cookie

前言

網路早期最大的問題之一是如何管理狀態。簡而言之,伺服器無法知道兩個請求是否來自同一個瀏覽器。當時最簡單的方法是在請求時,在頁面中插入一些參數,併在下一個請求中傳回參數。這需要使用包含參數的隱藏的表單,或者作為URL參數的一部分傳遞。這兩個解決方案都手動操作,容易出錯。cookie出現來解決這個問題。

作用

cookie是純文本,沒有可執行代碼。存儲數據,當用戶訪問了某個網站(網頁)的時候,我們就可以通過cookie來向訪問者電腦上存儲數據,或者某些網站為了辨別用戶身份、進行session跟蹤而儲存在用戶本地終端上的數據(通常經過加密)

如何工作

當網頁要發http請求時,瀏覽器會先檢查是否有相應的cookie,有則自動添加在request header中的cookie欄位中。這些是瀏覽器自動幫我們做的,而且每一次http請求瀏覽器都會自動幫我們做。這個特點很重要,因為這關係到“什麼樣的數據適合存儲在cookie中”。

存儲在cookie中的數據,每次都會被瀏覽器自動放在http請求中,如果這些數據並不是每個請求都需要發給服務端的數據,瀏覽器這設置自動處理無疑增加了網路開銷;但如果這些數據是每個請求都需要發給服務端的數據(比如身份認證信息),瀏覽器這設置自動處理就大大免去了重覆添加操作。所以對於那種設置“每次請求都要攜帶的信息(最典型的就是身份認證信息)”就特別適合放在cookie中,其他類型的數據就不適合了。

特征

  1. 不同的瀏覽器存放的cookie位置不一樣,也是不能通用的。
  2. cookie的存儲是以功能變數名稱形式進行區分的,不同的域下存儲的cookie是獨立的。
  3. 我們可以設置cookie生效的域(當前設置cookie所在域的子域),也就是說,我們能夠操作的cookie是當前域以及當前域下的所有子域
  4. 一個功能變數名稱下存放的cookie的個數是有限制的,不同的瀏覽器存放的個數不一樣,一般為20個。
  5. 每個cookie存放的內容大小也是有限制的,不同的瀏覽器存放大小不一樣,一般為4KB。
  6. cookie也可以設置過期的時間,預設是會話結束的時候,當時間到期自動銷毀

cookie值既可以設置,也可以讀取。

設置

客戶端設置

document.cookie = '名字=值';
document.cookie = 'username=cfangxu;domain=baike.baidu.com'    並且設置了生效域

註意: 客戶端可以設置cookie 的下列選項:expires、domain、path、secure(有條件:只有在https協議的網頁中,客戶端設置secure類型的 cookie 才能成功),但無法設置HttpOnly選項。

伺服器端設置 
不管你是請求一個資源文件(如 html/js/css/圖片),還是發送一個ajax請求,服務端都會返回response。而response header中有一項叫set-cookie,是服務端專門用來設置cookie的。

Set-Cookie 消息頭是一個字元串,其格式如下(中括弧中的部分是可選的):
Set-Cookie: value[; expires=date][; domain=domain][; path=path][; secure]

註意: 一個set-Cookie欄位只能設置一個cookie,當你要想設置多個 cookie,需要添加同樣多的set-Cookie欄位。 
服務端可以設置cookie 的所有選項:expires、domain、path、secure、HttpOnly 
通過 Set-Cookie 指定的這些可選項只會在瀏覽器端使用,而不會被髮送至伺服器端。

讀取

我們通過document.cookie來獲取當前網站下的cookie的時候,得到的字元串形式的值,它包含了當前網站下所有的cookie(為避免跨域腳本(xss)攻擊,這個方法只能獲取非 HttpOnly 類型的cookie)。它會把所有的cookie通過一個分號+空格的形式串聯起來,例如username=chenfangxu; job=coding

修改 cookie

要想修改一個cookie,只需要重新賦值就行,舊的值會被新的值覆蓋。但要註意一點,在設置新cookie時,path/domain這幾個選項一定要舊cookie 保持一樣。否則不會修改舊值,而是添加了一個新的 cookie。

刪除

把要刪除的cookie的過期時間設置成已過去的時間,path/domain/這幾個選項一定要舊cookie 保持一樣。

註意

如果只設置一個值,那麼算cookie中的value; 設置的兩個cookie,key值如果設置的相同,下麵的也會把上面的覆蓋。

cookie的屬性(可選項)

過期時間

如果我們想長時間存放一個cookie。需要在設置這個cookie的時候同時給他設置一個過期的時間。如果不設置,cookie預設是臨時存儲的,當瀏覽器關閉進程的時候自動銷毀

註意:document.cookie = '名稱=值;expires=' + GMT(格林威治時間)格式的日期型字元串;

一般設置天數:new Date().setDate( oDate.getDate() + 5 ); 比當前時間多5天

一個設置cookie時效性的例子

function setCookie(c_name, value, expiredays){
    var exdate=new Date();
    exdate.setDate(exdate.getDate() + expiredays);
    document.cookie=c_name+ "=" + escape(value) + ((expiredays==null) ? "" : ";expires="+exdate.toGMTString())
}
使用方法:setCookie('username','cfangxu',30)
expires 是 http/1.0協議中的選項,在新的http/1.1協議中expires已經由 max-age 選項代替,兩者的作用都是限制cookie 的有效時間。expires的值是一個時間點(cookie失效時刻= expires),而max-age 的值是一個以秒為單位時間段(cookie失效時刻= 創建時刻+ max-age)。 
另外,max-age 的預設值是 -1(即有效期為 session );max-age有三種可能值:負數、0、正數。 
負數:有效期session; 
0:刪除cookie; 
正數:有效期為創建時刻+ max-age

cookie的域概念(domain選項)

domain指定了 cookie 將要被髮送至哪個或哪些域中。預設情況下,domain 會被設置為創建該 cookie 的頁面所在的功能變數名稱,所以當給相同功能變數名稱發送請求時該 cookie 會被髮送至伺服器。

瀏覽器會把 domain 的值與請求的功能變數名稱做一個尾部比較(即從字元串的尾部開始比較),並將匹配的 cookie 發送至伺服器。

客戶端設置

document.cookie = "username=cfangxu;path=/;domain=qq.com" 
如上:“www.qq.com" 與 "sports.qq.com" 公用一個關聯的功能變數名稱"qq.com",我們如果想讓 "sports.qq.com" 下的cookie被 "www.qq.com" 訪問,我們就需要用到 cookie 的domain屬性,並且需要把path屬性設置為 "/"。

服務端設置

Set-Cookie: username=cfangxu;path=/;domain=qq.com 
註:一定的是同域之間的訪問,不能把domain的值設置成非主域的功能變數名稱。

cookie的路徑概念(path選項)

cookie 一般都是由於用戶訪問頁面而被創建的,可是並不是只有在創建 cookie 的頁面才可以訪問這個 cookie。 
因為安全方面的考慮,預設情況下,只有與創建 cookie 的頁面在同一個目錄或子目錄下的網頁才可以訪問。
即path屬性可以為伺服器特定文檔指定cookie,這個屬性設置的url且帶有這個首碼的url路徑都是有效的。

客戶端設置

 最常用的例子就是讓 cookie 在根目錄下,這樣不管是哪個子頁面創建的 cookie,所有的頁面都可以訪問到了。

document.cookie = "username=cfangxu; path=/"

服務端設置

Set-Cookie:name=cfangxu; path=/blog

如上設置:path 選項值會與 /blog,/blogrool 等等相匹配;任何以 /blog 開頭的選項都是合法的。需要註意的是,只有在 domain 選項核實完畢之後才會對 path 屬性進行比較。path 屬性的預設值是發送 Set-Cookie 消息頭所對應的 URL 中的 path 部分。

domain和path總結:

domain是功能變數名稱,path是路徑,兩者加起來就構成了 URL,domain和path一起來限制 cookie 能被哪些 URL 訪問。 
所以domain和path2個選項共同決定了cookie何時被瀏覽器自動添加到請求頭部中發送出去。如果沒有設置這兩個選項,則會使用預設值。domain的預設值為設置該cookie的網頁所在的功能變數名稱,path預設值為設置該cookie的網頁所在的目錄。

cookie的安全性(secure選項)

通常 cookie 信息都是使用HTTP連接傳遞數據,這種傳遞方式很容易被查看,所以 cookie 存儲的信息容易被竊取。假如 cookie 中所傳遞的內容比較重要,那麼就要求使用加密的數據傳輸。

secure選項用來設置cookie只在確保全全的請求中才會發送。當請求是HTTPS或者其他安全協議時,包含 secure 選項的 cookie 才能被髮送至伺服器。

document.cookie = "username=cfangxu; secure"

把cookie設置為secure,只保證 cookie 與伺服器之間的數據傳輸過程加密,而保存在本地的 cookie文件並不加密。就算設置了secure 屬性也並不代表他人不能看到你機器本地保存的 cookie 信息。機密且敏感的信息絕不應該在 cookie 中存儲或傳輸,因為 cookie 的整個機制原本都是不安全的

註意:如果想在客戶端即網頁中通過 js 去設置secure類型的 cookie,必須保證網頁是https協議的。在http協議的網頁中是無法設置secure類型cookie的。

httpOnly

這個選項用來設置cookie是否能通過 js 去訪問。預設情況下,cookie不會帶httpOnly選項(即為空),所以預設情況下,客戶端是可以通過js代碼去訪問(包括讀取、修改、刪除等)這個cookie的。當cookie帶httpOnly選項時,客戶端則無法通過js代碼去訪問(包括讀取、修改、刪除等)這個cookie。

在客戶端是不能通過js代碼去設置一個httpOnly類型的cookie的,這種類型的cookie只能通過服務端來設置。

cookie的編碼

cookie其實是個字元串,但這個字元串中等號、分號、空格被當做了特殊符號。所以當cookie的 key 和 value 中含有這3個特殊字元時,需要對其進行額外編碼,一般會用escape進行編碼,讀取時用unescape進行解碼;當然也可以用encodeURIComponent/decodeURIComponent或者encodeURI/decodeURI

第三方cookie

通常cookie的域和瀏覽器地址的域匹配,這被稱為第一方cookie。那麼第三方cookie就是cookie的域和地址欄中的域不匹配,這種cookie通常被用在第三方廣告網站。為了跟蹤用戶的瀏覽記錄,並且根據收集的用戶的瀏覽習慣,給用戶推送相關的廣告。 

  • cookie推薦資源

    • 聊一聊 cookie
    • HTTP cookies 詳解


localStorage(本地存儲)

HTML5新方法,不過IE8及以上瀏覽器都相容。

特點

  • 生命周期:持久化的本地存儲,除非主動刪除數據,否則數據是永遠不會過期的。
  • 存儲的信息在同一域中是共用的。
  • 當本頁操作(新增、修改、刪除)了localStorage的時候,本頁面不會觸發storage事件,但是別的頁面會觸發storage事件。
  • 大小:據說是5M(跟瀏覽器廠商有關係)
  • 在非IE下的瀏覽中可以本地打開。IE瀏覽器要在伺服器中打開。
  • localStorage本質上是對字元串的讀取,如果存儲內容多的話會消耗記憶體空間,會導致頁面變卡
  • localStorage受同源策略的限制

設置

localStorage.setItem('username','cfangxu');

獲取

localStorage.getItem('username') 
也可以獲取鍵名 
localStorage.key(0) #獲取第一個鍵名

刪除

localStorage.removeItem('username') 
也可以一次性清除所有存儲 
localStorage.clear()

storage事件

當storage發生改變的時候觸發。 
註意: 當前頁面對storage的操作會觸發其他頁面的storage事件 
事件的回調函數中有一個參數event,是一個StorageEvent對象,提供了一些實用的屬性,如下表:

PropertyTypeDescription
key String The named key that was added, removed, or moddified
oldValue Any The previous value(now overwritten), or null if a new item was added
newValue Any The new value, or null if an item was added
url/uri String The page that called the method that triggered this change


sessionStorage

其實跟localStorage差不多,也是本地存儲,會話本地存儲

特點:

  • 用於本地存儲一個會話(session)中的數據,這些數據只有在同一個會話中的頁面才能訪問並且當會話結束後數據也隨之銷毀。因此sessionStorage不是一種持久化的本地存儲,僅僅是會話級別的存儲。也就是說只要這個瀏覽器視窗沒有關閉,即使刷新頁面或進入同源另一頁面,數據仍然存在。關閉視窗後,sessionStorage即被銷毀,或者在新視窗打開同源的另一個頁面,sessionStorage也是沒有的。


cookie、localStorage、sessionStorage區別

  • 相同:在本地(瀏覽器端)存儲數據
  • 不同:

    localStorage、sessionStorage

    localStorage只要在相同的協議、相同的主機名、相同的埠下,就能讀取/修改到同一份localStorage數據。

    sessionStorage比localStorage更嚴苛一點,除了協議、主機名、埠外,還要求在同一視窗(也就是瀏覽器的標簽頁)下。

    localStorage是永久存儲,除非手動刪除。

    sessionStorage當會話結束(當前頁面關閉的時候,自動銷毀)

    cookie的數據會在每一次發送http請求的時候,同時發送給伺服器而localStorage、sessionStorage不會。

 

擴展其他的前端存儲方式(不常用)

web SQL database

先說個會被取代的,為什麼會被取代,主要有以下幾個原因:

  1. W3C捨棄 Web SQL database草案,而且是在2010年年底,規範不支持了,瀏覽器廠商已經支持的就支持了,沒有支持的也不打算支持了,比如IE和Firefox。
  2. 為什麼要捨棄?因為 Web SQL database 本質上是一個關係型資料庫,後端可能熟悉,但是前端就有很多不熟悉了,雖然SQL的簡單操作不難,但是也得需要學習。
  3. SQL熟悉後,真實操作中還得把你要存儲的東西,比如對象,轉成SQL語句,也挺麻煩的。

indexedDB

來自MDN的解釋: indexedDB 是一種低級API,用於客戶端存儲大量結構化數據(包括, 文件/ blobs)。該API使用索引來實現對該數據的高性能搜索。雖然 Web Storage 對於存儲較少量的數據很有用,但對於存儲更大量的結構化數據來說,這種方法不太有用。IndexedDB提供了一個解決方案。

所以,IndexedDB API是強大的,但對於簡單的情況可能看起來太複雜了,所以要看你的業務場景來選擇到底是用還是不用。

indexedDB 是一個基於JavaScript的面向對象的資料庫。 IndexedDB允許你存儲和檢索用鍵索引的對象;

IndexedDB 鼓勵使用的基本模式如下所示:

  • 打開資料庫並且開始一個事務。
  • 創建一個 object store。
  • 構建一個請求來執行一些資料庫操作,像增加或提取數據等。
  • 通過監聽正確類型的 DOM 事件以等待操作完成。
  • 在操作結果上進行一些操作(可以在 request 對象中找到)

1、首先打開indexedDB資料庫

語法: 
window.indexedDB.open(dbName, version)

var db;
// 打開資料庫,open還有第二個參數版本號
var request = window.indexedDB.open('myTestDatabase');
// 資料庫打開成功後
request.onsuccess = function (event) {
    // 存儲數據結果,後面所有的資料庫操作都離不開它。
    db = request.result;
}
request.onerror = function (event) {
    alert("Why didn't you allow my web app to use IndexedDB?!");
}

// 資料庫首次創建版本,或者window.indexedDB.open傳遞的新版本(版本數值要比現在的高)
request.onupgradeneeded = function (event) {

}

onupgradeneeded事件: 更新資料庫的 schema,也就是創建或者刪除對象存儲空間,這個事件將會作為一個允許你處理對象存儲空間的 versionchange 事務的一部分被調用。在資料庫第一次被打開時或者當指定的版本號高於當前被持久化的資料庫的版本號時,這個 versionchange 事務將被創建。onupgradeneeded 是我們唯一可以修改資料庫結構的地方。在這裡面,我們可以創建和刪除對象存儲空間以及構建和刪除索引。

2、構建資料庫

IndexedDB 使用對象存儲空間而不是表,並且一個單獨的資料庫可以包含任意數量的對象存儲空間。每當一個值被存儲進一個對象存儲空間時,它會被和一個鍵相關聯。

  // 資料庫首次創建版本,或者window.indexedDB.open傳遞的新版本(版本數值要比現在的高)
  request.onupgradeneeded = function (event) {

      //之前咱們不是在success中得到了db了麽,為什麼還要在這獲取,
      //因為在當前事件函數執行後才會去執行success事件
      var db = event.target.result;

      // 創建一個對象存儲空間,keyPath是id,keyGenerator是自增的
      var objectStore = db.createObjectStore('testItem',{keyPath: 'id',autoIncrement: true});
      // 創建一個索引來通過id搜索,id是自增的,不會有重覆,所以可以用唯一索引
      objectStore.createIndex('id','id',{unique: true})

      objectStore.createIndex('name','name');
      objectStore.createIndex('age','age');

      //添加一條信息道資料庫中
      objectStore.add({name: 'cfangxu', age: '27'});

  }

註意: 執行完後,在調試工具欄Application的indexedDB中也看不到,你得右鍵刷新一下。

創建索引的語法:

objectStore.createIndex(indexName, keyPath, objectParameters)

indexName:創建的索引名稱,可以使用空名稱作為索引。
keyPath:索引使用的關鍵路徑,可以使用空的keyPath, 或者keyPath傳為數組keyPath也是可以的。
objectParameters:可選參數。常用參數之一是unique,表示該欄位值是否唯一,不能重覆。例如,本demo中id是不能重覆的,於是有設置:

3、添加數據

上面的代碼建好了欄位,並且添加了一條數據,但是我們如果想在onupgradeneeded事件外面操作,接下來的步驟了。 
由於資料庫的操作都是基於事務(transaction)來進行,於是,無論是添加編輯還是刪除資料庫,我們都要先建立一個事務(transaction),然後才能繼續下麵的操作。 
語法: var transaction = db.transaction(dbName, "readwrite"); 
第一個參數是事務希望跨越的對象存儲空間的列表,可以是數組或者字元串。如果你希望事務能夠跨越所有的對象存儲空間你可以傳入一個空數組。如果你沒有為第二個參數指定任何內容,你得到的是只讀事務。因為這裡我們是想要寫入所以我們需要傳入 "readwrite" 標識。

var timer = setInterval(function () {
    if(db) {
        clearInterval(timer);
        // 新建一個事務
        var transaction = db.transaction(['testItem'], 'readwrite');
        // 打開一個存儲對象
        var objectStore = transaction.objectStore('testItem');
        // 添加數據到對象中
        objectStore.add({ name: 'xiaoming', age: '12' });
        objectStore.add({ name: 'xiaolong', age: '20' });
    }
},100)

為什麼要用一個間隔定時器? 因為這是一個demo,正常的是要有操作才能進行資料庫的寫入,在我們的demo中,js執行到transaction會比indexedDB的onsuccess事件回調快,導致會拿到db為undefined,所以寫了個間隔定時器等它一會。

4、獲取數據

var transaction = db.transaction(['testItem'], 'readwrite');

var objectStore = transaction.objectStore('testItem');

var getRquest = objectStore.get(1);
getRquest.onsuccess = function (event) {
    console.log(getRquest.result);
}
//輸出:{name: "cfangxu", age: "27", id: 1}

5、修改數據

var transaction = db.transaction(['testItem'], 'readwrite');

var objectStore = transaction.objectStore('testItem');

var getRquest = objectStore.put({ name: 'chenfangxu', age: '27', id:1 });
// 修改了id為1的那條數據

6、刪除數據

var transaction = db.transaction(['testItem'], 'readwrite');

var objectStore = transaction.objectStore('testItem');

var getRquest = objectStore.delete(1);
// 刪除了id為1的那條數據
上面的例子執行完後,一定一定要右鍵刷新indexedDB,它自己是不會變的。
我有一個前端學習交流QQ群:328058344 如果你在學習前端的過程中遇到什麼問題,歡迎來我的QQ群提問,群里每天還會更新一些學習資源。禁止閑聊,非喜勿進。

您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 寫在前面 兩欄佈局是指頁面佈局由主欄和邊欄組成,是許多網頁的佈局方式,一般使用CSS去實現兩欄佈局。 實現兩欄佈局的方式有多種,這裡採用四種比較常見的實現方式。主要是流體佈局(liquid layouts),凝膠佈局(Jello layouts),絕對佈局(absolute layouts),表格布 ...
  • 使用vue-cli 建立項目 package.json 安裝好sass之後,想要在組件中使用全局變數 sass-resources-loader 安裝方法 步驟1:npm i sass-resources-loader --save-dev 步驟2:修改build/utils.js 在以下代碼的 上 ...
  • 排序演算法主要用在元素的數組排序,常見的排序演算法有冒泡排序、選擇排序、插入排序、希爾排序、快速排序、歸併排序等。這些排序演算法都可以用JavaScript實現。下麵的排序演算法都假設是從小到大進行排序,從大到小可以相應進行轉化。 冒泡排序 冒泡排序的基本思想是從頭遍歷要排序的數組,比較相鄰兩個數,如果前面 ...
  • 最簡單的方式就是創建一個文本文檔,然後將.txt尾碼改為.html或者htm。 完成上面的步驟會創建一個完全空白的網頁,下麵填充一點內容,代碼實例如下: 上面的代碼會創建一個顯示"螞蟻部落"的網頁。 網頁的具體結構和元素組成會在後面的章節分步介紹。 http://www.softwhy.com/ar ...
  • 一.背景介紹: css不是一種真正意義上的編程語言,不具有編程語言的變數、迴圈、遍歷和繼承等特性。 為瞭解決css的這些缺點,能夠對css進行預處理的"中間語言"就產生了,以此來實現某些編程特性。 也就是在編寫中間語言過程中,可以使用編程方式和思維,中間語言不能直接被瀏覽器所解析。 最後將這個中間語 ...
  • 一.正則表達式基本介紹: 實際應用中,經常需要按照某些規則去操作字元串,正則表達式恰好是制定這些規則的利器。 正則表達的英文全程是regular expression,正如它的名字,可以將它分為兩個部分來理解: (1).第一部分是規則(regular),用來約束各個字元的語義。例如點(.)可以表示任 ...
  • 一.jQuery是什麼: 它是一個輕量級的JavaScript庫。所以遵循JavaScript語法,並具有自身的特點。 二.jQuery的優勢: (1).具有良好的瀏覽器相容性,所有主流瀏覽器對jQuery有著良好支持。 (2).實現了腳本與頁面分離,頁面更加清晰,也有利於搜索引擎優化。 (3).高 ...
  • 首先,vue和阿裡雲oss上傳圖片結合參考了 這位朋友的 https://www.jianshu.com/p/645f63745abd 文章,成功的解決了我用阿裡雲oss上傳圖片前的一頭霧水。 該大神文章里有寫github地址,裡面的2.0分支採用vue2.0實現,只不過這個上傳圖片用的是分片上傳, ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...