[解讀REST] 6.REST的應用經驗以及教訓

来源:http://www.cnblogs.com/linianhui/archive/2017/10/21/rest_experience.html
-Advertisement-
Play Games

銜接上文[解讀REST] 5.Web的需求 & 推導REST,上文根據Web的需求推導出了REST架構風格,以及REST的詳細描述和解釋。自從1994年以來,REST架構風格被用於指導Web架構的設計和開發工作,最重要的兩點體現是在設計HTTP和URI兩個互聯網規範協議中,以及實現這些規範的libw ...


銜接上文[解讀REST] 5.Web的需求 & 推導REST,上文根據Web的需求推導出了REST架構風格,以及REST的詳細描述和解釋。自從1994年以來,REST架構風格被用於指導Web架構的設計和開發工作,最重要的兩點體現是在設計HTTP和URI兩個互聯網規範協議中,以及實現這些規範的libwww-perl客戶端庫,Apache HTTP項目(httpd)以及其他的實現中,所得到的經驗以及教訓。

其實REST也用於指導約束超媒體的設計工作,比如HTML,但是Fielding並未在論文中詳細解釋這部分(很遺憾的一件事情)。所以也造成瞭如今大家普遍對REST的片面理解,這也造成了大家都i不把超媒體這部分作為REST的重要組成部分來考慮。為此Fielding博士在08年專門寫過一篇文章來解釋:http://roy.gbiv.com/untangled/2008/rest-apis-must-be-hypertext-driven

1 Web標準化

本系列在一開始就提到,創造REST的目的就是為Web創建一個架構模型,使其來指導Web的架構設計以及相關的協議規範的開發。用REST來描述Web所期待的架構,識別出現的問題,對各種方案進行對比,並且保證新的協議不會違反使Web成功的那些個核心約束。這部分工作使IETF和W3C來負責的,它們定義了HTTP,URI,HTML這三個核心的規範。一開始這三個規範都使由IETF來負責的,後來Web之父Berners-Lee創建了W3C,使其作為Web架構的智庫,併為Web編寫規範以及實現相關所需的資源,隨後HTML就由W3C來專職負責了(關於這部分的歷史緣由就不解釋了,感興趣的朋友自行瞭解吧)。

得益於Fielding博士在Web開發方面的經驗,他被IETF旋轉來創作URL規範,後來又和Henrik Frystyk Nielsen合作創作了HTTP/1,0,後來Fielding博士成了HTTP/1.1的主要架構師,並且最終創作了URI通用語法標準的URL規範的修訂版。

REST的第一版誕生於1994年10到1995年8月之間,起初使Fielding作為編寫HTTP1.0的一種概念方法。在隨後的5年中不斷的迭代改進,並且用於各種Web協議標準的修行版和擴展之中。最初REST被稱作“HTTP對象模型”,很容易被誤解為它使一個HTTP伺服器的實現模型。而REST(表述性狀態移交)這個詞使有意喚起人們對於一個設計良好的Web應用如何運轉的印象:Web應用使一個由網頁組成的網路(一個虛擬狀態機),用戶通過選擇鏈接(狀態遷移)在應用中前進,引導系統把下一個頁面(代表應用的下一個狀態)的數據移交給用戶,並且呈現出來,以便用戶使用其中承載包含應用狀態的部分是有超媒體來負責的,這也是為什麼REST強調HATEOAS(Hypermedia As The Engine Of Application Statue)的原因所在

REST並未想要捕獲到Web協議規定所有可能的使用方法,現實中仍然會存在一些於REST不匹配的Web應用存在。但是REST捕獲到了Web作為一個分散式超媒體系統中最重要的方面,然後對這方面進行優化,使得Web可以滿足最核心的這部分需求。

2 把REST應用於URI

 URI既是Web中最簡單的元素,也是最重要的元素。其中URL和URN是常見的兩種形式。URI的語法自從1992年以來都相對穩定。URI中也定義了“資源”的概念以及其語義,但是這個概念以及發生了很大的變化。REST用來定義URI中“資源”這個術語,以及定義通過它們的表述操作資源的通用介面的全部語義

2.1 重新定義資源

早期Web把URI定義為文檔的標識符。創作者使用網路上一個文檔的位置來定義標識符,其他人然後通過Web協議來獲取這個文檔。但是這個定義並不合適,首先這暗示者創作者正在標識所移交的內容,也就是意味者如果文檔的內容改變了,那麼這個標識符也應該改變;其次,存在很多地址對應的一個服務,而不是一個文檔;最後,可能有一段時間沒有這個文檔。

REST對於“資源”的定義有一個前提:標識符應該儘可能的少改變。原因在於Web使用的是內嵌的標識符,而不是鏈接伺服器。這個內嵌的標識符標識著特定的語義,允許保持對這個標識符的引用,即便是該標識符背後的資源發生了變化,但是其語義並未發生變化。也就是說REST把URI這個標識符定義為資源所要表達的語義,而不是語義背後對應的具體的值。

2.2 表述

把“資源”定義為URI標識的”一個概念“,而不是一個具體的文檔,這導致了另外的一個問題:用戶如何訪問操作“一個概念"呢?REST引入了”表述“這個中間層,即通過資源的表述來操作資源,而不是直接在資源本身上進行操作(一個來源伺服器維護者資源的標識符和其對應的表述的映射關係,因此可以通過由資源標識符定義的通用介面移交表述來操作一個資源)。

REST對於資源的定義來自於Web的核心需求:獨立創作跨越多個可信任的組織邊界的互相鏈接的超文本。強制要求介面的定義和介面的需求相匹配,會使得協議看起來模糊不清,但這僅僅是因為被操作的僅僅是一個介面,而不是一個實現。所以資源和介面背後的實現細節都應該是被隱藏起來的,通過介面和表述這兩個獨立的概念來隔離介面和資源的這兩者的具體實現,這也是REST的統一介面這個架構約束的動機。

由HTTP和URI組成了介面,HTML作為資源的表述,使得來源伺服器的對介面和資源的具體實現得以統一標準化。同時得益於客戶端不再直接操作資源,使得客戶端可以選擇自己所能理解的表述來操作資源,比如如今的網站可以提供PC版的Web Site,同時提供基於JSON格式的API來操作同一個資源。再進一步,比如某一個網站的實現從.net升級為了net core,伺服器從windows換成了centos,web伺服器從iis換成了ngnix,資料庫從sql server換成了mysql等等,只要其基於URI和HTTP提供的介面未發生變化,某一個API的語義未發生變化,這一切對於客戶端來說,都是透明的。這就使得Web的各種組件的獨立部署成為了可能。--筆者解讀

2.3 把語義綁定到URI

如上面舉得例子,一個資源可以由多個URL(PC網頁版,基於JSON的API版)來操作,當訪問這兩個URL的時候,其語義是相同的。當然也可能由兩個URL,訪問的時候,伺服器使用了相同的機制,但是這兩個URL卻是兩個不同的資源。

對於通過資源的標識符和表述來操作資源的行為而言,語義是一個副產品(比如在網頁上執行登錄,付款這兩個操作,對於Web的各部分組件來說,並不理解其中的差異,其背後的動作很可能都是post一個請求而已)。語義這部分是交由最終用戶來解讀的,關於語義這部分這裡不細說了(其背後由協議語義,應用語義等具體的概念),後面專門寫博客來解釋。

2.4 URI中不匹配REST的情況

理想是豐滿的,現實是殘酷的。並非所有的已經部署的Web組件都遵循Web的設計要求,REST既可以用來定義Web的改進辦法,也可以作為識別其中不匹配部分的方法,儘管無法避免這些不匹配,但是可以在其成為正式規範之前識別出來它們。

儘管URI的設計和REST中標識符的概念相匹配,但是僅僅依靠URI的語法規則是不足以約束不匹配的行為的。其中的一種濫用就是在URL中包含當前用戶的信息,這樣的辦法可以用於維護伺服器會話的狀態,但是也會降低共用緩存的效率,也會降低伺服器的可伸縮性,並且如果一個用戶把這個URL發給其他的用戶時,會得到不希望看到的結果。這其實時違反了REST的無狀態的約束。另外一個便是把Web看作是一個分散式的文件系統的時候,因為文件系統其實是暴露了其實現細節。

3 把REST應用於HTTP

HTTP在Web中是一個特殊的角色,它既是Web組件之間通信的的應用級協議,也是作為移交資源的表述而設計的唯一協議(註:Fielding發佈REST的論文是在2000年,而在2014年又但是了一個COAP協議,所以以現在時間點來看,HTTP已經不是唯一的協議了)。REST用來識別早期HTTP協議中的問題,並指定了一個可以和HTTP1.0互操作的協議自己,然後分析HTTP1.1的擴展提議,並最終誕生了HTTP1.1。

2014年IETF發佈的的COAP(RFC 7252 Constrained Application Protocol)協議,也是遵循REST的指導來設計的,用於IOT的M2M環境下的應用層協議。COAP可以簡單的理解為使HTTP的二進位精簡版,此外其基於UDP協議,而不是HTTP所使用的TCP。不過目前應用並不廣泛,IBM在1998開發的基於TCP的MQTT協議出現的比較早,相關資源豐富一些,因此目前在IOT領域MQTT應用的比較廣泛一些。

3.1 可擴展性

REST的主要目標之一就是對一個以及部署的架構進行片段式的升級部署。為此為HTTP添加了版本控制,通過主版本和次版本號來區分(1.0 1.1 2.0),其版本信息代表的是消息發送者對協議的支持能力。

HTTP包含了很多的部分,比如URI模式,媒體類型,MIME等,這些部分是由單獨協議來控制的。HTTP自身也管理了一些比如方法名稱,響應狀態碼,HTTP中各種的Header信息。HTTP請求的語義由請求方法來表示,對於這個語義是在各個組件直接共用的。再比如響應狀態碼(1xx,2xx,3xx,4xx,5xx)分別表示一類信息,方便後續進行擴充。

HTTP1.1也新增了Upgrade頭,用來再通信雙方進行協商協議版本。

3.2 自描述的消息

HTTP要求組件直接的消息是自描述的,以便支持中間件對交互進行處理。但是早期的HTTP協議在一些方面並不是自描述的。

Host請求頭:早期的HTTP請求中不會攜帶host頭部信息,這導致了一個IP上只能部署一個服務。

分層編碼:HTTP為了描述表述的元數據,採用可MIME的語法,MIME沒有定義分層的媒體類型。

傳輸獨立性:早期的HTTP協議,使用了底層的傳輸協議來表示響應結束,比如伺服器通過關閉TCP連接來表明響應消息的結束。這導致一個嚴重的問題,就是客戶端無法無法到底是網路故障導致的斷開,還是伺服器主動斷開的。為此HTTP1.1加入了Content-Length,用來表示消息體的長度,並且加入了chunked這個編碼格式,允許伺服器在事先不知道Content-Lenth的情況下。

緩存控制:新增的Cache-Control,Age,Etag等更精確的緩存控制。

性能:早期的HTTP協議每個連接只允許發送單個請求和響應,這導致對TCP的使用非常低效。受限於已經部署的組件,HTTP1.1把預設的持久連接作為了預設的選項,如果要關閉連接,則需要發送close的指令。

3.3 HTTP中不匹配REST的情況

這些不匹配是由於部署的第三方擴展或者是為了保證和HTTP1.0的相容所導致的。

區分權威的響應:既無法區分一個響應是來自於源伺服器還是中間的某一個組件,雖然HTTP1.1中定義了Warning消息頭,但是並未廣泛使用。

cookie:cookie作為一個站點範圍內的黑盒狀態信息,會導致基於Cookie的交互於REST的應用狀態的模型不匹配(比如上一個頁面設置了一個cookie,但是下一個頁面或許並不依賴cookie,然而cookie也會被髮送出去)。其次其cookie並沒有任何的語義信息,只是一段文本消息,這也會導致完全和隱私方便的問題,比如如今的各種的廣告使用的第三方cookie,對用戶的追蹤,造成的隱私和安全問題。

混合元數據:我記得HTTP權威指南中把Header分為請求,響應,實體,通用等部分。其實這部分Header按照其用途應該在HTTP本身進行分門別類一下,比如操作的元數據、資源的、表述的、協議控制的和認證的等等用途。如果得以分層和劃分,則有助於對消息的處理。

將響應和請求匹配:從HTTP的響應消息中,並不能知道其是由那個請求發出的,只能依賴底層的實現。比如如果每一個請求都會有一個Request-Id,然後在其響應中原樣返回。

4 技術推廣

儘管REST對於Web的標準規範又最直接的影響,但是把它作為架構設計模型,則是通過各種形式的實現來驗證的。比如libwww-perl庫,Apache的httpd,早期的IE,網景等。REST架構風格成功的指導了Web的架構設計和部署,到目前為止(從199年的http1.1發佈到如今),Web並未出現嚴重的問題。而CDN網路(緩存)的出現也顯著的改善了用戶改製的性能。

5 架構上的教訓

從Web架構和由REST識別出來的問題中,可以總結出來很多通用的架構上的教訓。

5.1 基於網路的API的優勢

把Web和其他的中間件區分的一個標誌是它使用HTTP作為一個基於網路的API。但是並不是一項如此,早期的Web利用了一個程式庫(CERN的libwww)作為所有客戶端和伺服器軟體所使用的單個協議實現庫,libwww提供了一個基於庫的api來構造可互操作的Web組件。

5.2 HTTP不是RPC

人們通常錯誤的把HTTP視為一種RPC機制,僅僅因為它也是由請求和響應組成的。RPC從本質上來講,是把一個函數調用放到了跨越網路的另一端,使其使用者看來就像是在調用本地函數一樣,RMI也是類似的機制和目的。把HTTP和RPC分開的並不是其調用細節,而在於其對待網路的影響是怎樣看待的,前者側重於如何有效的利用網路,而後者則在於如何屏蔽網路帶來的影響。

HTTP是基於網路而專門設計的應用層協議:它的請求被定向到使用了一個標準的語義的通用介面的組件上,而這個組件可以採用幾乎和最終的伺服器完全相同的方式來解釋這個請求以及其語義,並提供響應。這就可以基於HTTP構建起來一個支持分層轉換的系統(比如緩存,代理,網關都屬於其中的具體層級),這對於一個基於互聯網規模的、跨域多個組織邊界的、無法控制的可伸縮性的系統而已,意義是巨大的。

而RPC,則是根據編程語言的API來定義的,雖然現在眾多的RPC框架可以支持很多的語言平臺,但是其本質還是在有描述一個方法的調用罷了,比如SOAP乾的事情本質上就是描述要調用的方法是什麼名字,傳什麼類型的參數,返回什麼類型的數據等等這些事情。

5.3 HTTP不是傳輸協議

HTTP並不是被設計為一種傳輸協議。它是一種移交協議。在HTTP中,通過對資源的表述執行各種動作,其反應出來的是Web架構的語義。使用這個非常簡單的介面來實現各種的功能是可能的,前提是必須要遵循這個介面,以便HTTP的協議語義對於中間件而已是可見的,這也是為何HTTP可以穿透防火牆的原因。重點在於Web的各各組件都理解HTTP的協議語義,從而可以獨自的完成HTTP的響應,而不必一定到達最終的源伺服器,這也是為什麼它不是傳輸協議的原因。

5.4 媒體類型的設計

這是REST中最容易被忽視的一部分,也就是REST對於Web架構中的數據元素的影響程度。最頻繁出現的問題在於違反應用狀態和無狀態交互的架構約束。比如前面提到的Cookie,以及HTML中的iframe,這導致用戶代理無法管理和理解它們提供的間接應用狀態。

說點題外話,最近幾年火熱的前端框架(react,angular,vue),通常都會遇到SEO的問題,那麼這個問題產生的根源是什麼呢?原因在於HTML本來是承載著應用狀態的超媒體語言,瀏覽器可以理解它,可以通過a,form這些超媒體控制項來移交應用的狀態,網路爬蟲也可以理解這些信息,從而構造出一個網狀的狀態遷移圖。但是呢,前端的框架則打破了這種形態,把HTML近作為了一種UI顯示語言來用,應用的狀態遷移全都交給了js(js是作為REST的按需代碼這一可選的架構約束的具體實現來存在的),這就導致了Web瀏覽器和網路爬蟲得到的只有一些作為UI模板用的HTML,而不知其應用狀態在何處。目前這些前端框架做出來的網站,其實是把按需代碼這一約束髮揮到了極致,其本質上是一個本地應用,只是它的UI語言和業務語言分別是HTML和JS,而這兩者可以通過網路來動態的部署罷了。Web APP,首先它具有的一個APP的特征,其次才是Web的特征。

再比如electron,基於此開發的各種桌面應用(VS Code既是基於它),採用了HTML,CSS,JS來開發一個桌面應用,這其實已經和Web沒有絲毫關係了。而是得益於可以解析HTML,CSS,JS背後的運行時可以方便的跨平臺。

當然說這些並不是批判,而是感嘆HTML和JS的的生名力會越來越頑強。Web在蠶食能觸及到的方方面面,同時能用JS重寫的地方,最終都會被JS重寫。

HTML本身具有的增量處理的特性,使得瀏覽器可以在下載的同時進行頁面的渲染,以及進來提供的預先載入的機制可以提前下載js,css,圖片,甚至是另外一個HTML網頁,從而提升用戶感知的性能。迄今為止,HTML可以說是最為成功的一個超媒體的例子。

6 總結

本篇博客解釋了REST在設計Web的標準協議以及實現具體的Web組件中所起到的作用,以及現實中那些並不匹配REST要求的部分和從中得到的經驗以及教訓。

關於REST的論文的解讀,本篇是最後一篇,絕大部分的內容來源於Fielding博士的論文,畢竟REST這個術語誕生於此,論文本身比較晦澀難懂(其實這也不怪Fielding博士,這篇論文是寫給IETF和W3C的專家組看的,為此Fielding博士還專門解釋過這件事情:http://roy.gbiv.com/untangled/2008/specialization。),這也從側面說明論文中所包含的信息是非常具有價值的,比如關於架構風格和架構的解釋,對於基於網路的應用的架構風格的總結和比較,以及REST本身,是非常值得花時間去讀一讀的。

由於筆者本身理解能力也有限,難免有些地方會理解不周或者出現偏差,歡迎大家指正。這個系列的主要意義在於以正確的角度來看待和理解REST,而不要把REST和RESTful API混在一起,後續筆者關於RESTful API的理解會單獨來寫。

參考

世界上誕生的第一個網站:http://info.cern.ch/

世界上誕生的第一個網站-模擬器:http://line-mode.cern.ch/www/hypertext/WWW/TheProject.html

Web的生日:http://home.cern/topics/birth-web

理解本真的REST:http://www.infoq.com/cn/articles/understanding-restful-style/

架構風格與基於網路的軟體架構設計-導讀:http://www.infoq.com/cn/articles/doctor-fielding-article-review

架構風格與基於網路的軟體架構設計:http://www.infoq.com/cn/minibooks/web-based-apps-archit-design

Architectural Styles and the Design of Network-based Software Architectures:https://www.ics.uci.edu/~fielding/pubs/dissertation/top.htm

Roy T. Fielding: Understanding the REST Style:https://www.youtube.com/watch?v=w5j2KwzzB-0

Roy T. Fielding: REST APIs must be hypertext-driven: http://roy.gbiv.com/untangled/2008/rest-apis-must-be-hypertext-driven

Roy T. Fielding: It is ok to use http:http://roy.gbiv.com/untangled/2009/it-is-okay-to-use-post

Evolution of HTTP:https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/Evolution_of_HTTP

REST is not about APIs , Part 1:https://www.nirmata.com/2013/10/01/rest-apis-part-1/

REST is not about APIs , Part 2:https://www.nirmata.com/2013/11/12/rest-apis-part-2/

REST知識的閱讀清單:http://www.infoq.com/cn/articles/rest-reading-list

What's different/better/worse than other JSON hypermedia media types?https://github.com/kevinswiber/siren/issues/15

API Design Guidelines :https://github.com/linianhui/api-standards

COAP (Constrained Application Protocol):http://coap.technology/


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

-Advertisement-
Play Games
更多相關文章
  • 題目描述 一組數,分別表示地平線的高度變化。高度值為整數,相鄰高度用直線連接。找出並統計有多少個可能積水的低窪地? 如圖:地高變化為 0 1 0 2 1 2 0 0 2 0 輸入輸出格式 輸入格式: 兩行,第一行n,表示有n個數。第2行連續n個數表示地平線高度變化的數據,保證首尾為0。(3<=n<= ...
  • InputStream is = null;try { is = new FileInputStream(textPath); BufferedReader reader = new BufferedReader(new InputStreamReader(is, "UTF-8"), 512); / ...
  • 1.功能簡介 此程式模擬員工信息資料庫操作,按照語法輸入指令即能實現員工信息的增、刪、改、查功能。 2.實現方法 架構: 本程式採用python語言編寫,關鍵在於指令的解析和執行:其中指令解析主要運用了正則表達式來高效匹配有效信息;指令執行通過一個commd_exe主執行函數和增、刪、改、查4個子執 ...
  • [摘要] 對 Base64 編碼的簡介,常用場景舉例,編、解碼流程,以及如何在 Python 中使用 Base64編碼與解碼 ...
  • FIRSTCRM 學員管理開發需求: 1.分講師\學員\課程顧問角色, 2.學員可以屬於多個班級,學員成績按課程分別統計 3.每個班級至少包含一個或多個講師 4.一個學員要有狀態轉化的過程 ,比如未報名前,報名後,畢業老學員 5.客戶要有咨詢紀錄, 後續的定期跟蹤紀錄也要保存 6.每個學員的所有上課 ...
  • 縱觀現狀:大學是一個自由的小社會,無憂無慮,天真爛漫,然而當你正式步入社會,你會漸漸明白“你今後人生的艱難,恰恰是在一個能讓自己自由充分成長的黃金四年裡,卻把自己荒廢了”。難道我們非要“後知後覺”嗎? 展望未來:如果你以後有意從事編程的相關工作,你應該要知道,在找工作時和其他競爭者拉開差距的,起絕對 ...
  • 關鍵資源 關鍵資源總是有限的,也就意味著處理能力也有限,所以當面對大量業務時,為了保障自己能夠有序的提供服務最經濟的做法就是限制同一時間處理的事務數。比如銀行的工作人員,一個工作人員同時只能為一個客戶服務,來多了根本處理不了,不光是一種浪費而且有可以造成混亂的局面導致工作人員無法工作。 網路請求漏斗 ...
  • 前臺: 支持三套模版, 可以在後臺切換 系統介紹: 1.網站後臺採用主流的 SSM 框架 jsp JSTL,網站後臺採用freemaker靜態化模版引擎生成html 2.因為是生成的html,所以訪問速度快,輕便,對伺服器負擔小 3.網站前端採用主流的響應式佈局,同一頁面同時支持PC、平板、手機(三 ...
一周排行
    -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.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...