<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Http on Wayne's blog | 偉恩的部落格 | 技術博客</title><link>https://blog.wayne-project.com/tags/http/</link><description>Recent content in Http on Wayne's blog | 偉恩的部落格 | 技術博客</description><generator>Hugo -- gohugo.io</generator><language>zh-tw</language><lastBuildDate>Sun, 24 Jul 2022 00:00:00 +0000</lastBuildDate><atom:link href="https://blog.wayne-project.com/tags/http/index.xml" rel="self" type="application/rss+xml"/><item><title>初學者都該了解的 HTTP 通訊協定基礎</title><link>https://blog.wayne-project.com/2022-07-24/beginner-http-lesson/</link><pubDate>Sun, 24 Jul 2022 00:00:00 +0000</pubDate><guid>https://blog.wayne-project.com/2022-07-24/beginner-http-lesson/</guid><description>&lt;img src="https://live.staticflickr.com/65535/52276290470_787c77a1b5_o.jpg" alt="Featured image of post 初學者都該了解的 HTTP 通訊協定基礎" /&gt;&lt;style&gt;
.focus {
background: #f1e2e2;
color: #d62c2c;
padding: 0 5px;
}
&lt;/style&gt;
&lt;p&gt;&lt;a class="link" href="https://youtu.be/Taq5TV1K4XU" target="_blank" rel="noopener"
&gt;參考網站 - 初學者都該學會的 HTTP 通訊協定基礎&lt;/a&gt;&lt;br&gt;
&lt;a class="link" href="https://totoroliu.medium.com/http-2-%E6%98%AF%E4%BB%80%E9%BA%BC-d7de699bdbae" target="_blank" rel="noopener"
&gt;參考網站 - Http/2 是什麼?&lt;/a&gt;&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="目前-http-通訊協定的版本"&gt;目前 HTTP 通訊協定的版本&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;HTTP/0.9
&lt;ul&gt;
&lt;li&gt;於 &lt;strong&gt;1991&lt;/strong&gt; 年發表(已廢止)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;HTTP/1.0
&lt;ul&gt;
&lt;li&gt;於 &lt;strong&gt;1996&lt;/strong&gt; 年 &lt;strong&gt;5&lt;/strong&gt; 月發表(&lt;a class="link" href="https://datatracker.ietf.org/doc/html/rfc1945" target="_blank" rel="noopener"
&gt;RFC 1945&lt;/a&gt;)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;HTTP/1.1
&lt;ul&gt;
&lt;li&gt;於 &lt;strong&gt;1997&lt;/strong&gt; 年 &lt;strong&gt;1&lt;/strong&gt; 月發表(&lt;a class="link" href="https://datatracker.ietf.org/doc/html/rfc2068" target="_blank" rel="noopener"
&gt;RFC 2068&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;於 &lt;strong&gt;1999&lt;/strong&gt; 年 &lt;strong&gt;6&lt;/strong&gt; 月發布 HTTP/1.1 更新版(&lt;a class="link" href="https://datatracker.ietf.org/doc/html/rfc2616" target="_blank" rel="noopener"
&gt;RFC 2616&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;於 &lt;strong&gt;2014&lt;/strong&gt; 年 &lt;strong&gt;6&lt;/strong&gt; 月再次更新 HTTP/1.1 並將規格文件拆成六份&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;HTTP/2(&lt;a class="link" href="https://zh.wikipedia.org/zh-tw/HTTP/2" target="_blank" rel="noopener"
&gt;Wikipedia&lt;/a&gt;)
&lt;ul&gt;
&lt;li&gt;於 &lt;strong&gt;2015&lt;/strong&gt; 年 &lt;strong&gt;5&lt;/strong&gt; 月發布(&lt;a class="link" href="https://datatracker.ietf.org/doc/html/rfc7540" target="_blank" rel="noopener"
&gt;RFC 7540&lt;/a&gt;)(&lt;a class="link" href="https://caniuse.com/?search=http2" target="_blank" rel="noopener"
&gt;瀏覽器相容性&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;僅針對 HTTP/1.1 的 Message Syntax 部分作出強化&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="http09-已廢止"&gt;HTTP/0.9 (已廢止)&lt;/h2&gt;
&lt;h3 id="概要"&gt;概要&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;於 &lt;strong&gt;1990&lt;/strong&gt; 年由 Tim Berners-Lee 提出最初的 &lt;strong&gt;HTTP&lt;/strong&gt; 建議(&lt;strong&gt;WWW&lt;/strong&gt;)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;實作重點&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;用戶端要求是以 &lt;strong&gt;ASCII&lt;/strong&gt; 字元為主(單行命令即可發出請求 GET/)&lt;/li&gt;
&lt;li&gt;用戶端要求會以一個 &lt;strong&gt;換行字元&lt;/strong&gt; (CRLF) 來結束&lt;/li&gt;
&lt;li&gt;伺服器回應是以 &lt;strong&gt;ASCII&lt;/strong&gt; 字元為主，回應內容是 &lt;strong&gt;HTML&lt;/strong&gt; 文件&lt;/li&gt;
&lt;li&gt;每次執行完 Request / Response 就會自動關閉連線&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;主要特色&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Client / Server 架構、Request / Response 協定&lt;/li&gt;
&lt;li&gt;跑在 &lt;strong&gt;TCP/IP&lt;/strong&gt; 上的 &lt;strong&gt;ASCII&lt;/strong&gt; 協定 (要求/回應)&lt;/li&gt;
&lt;li&gt;被設計用來傳輸 &lt;strong&gt;HTML&lt;/strong&gt; 文件&lt;/li&gt;
&lt;li&gt;每完成一次 &lt;strong&gt;ASCII&lt;/strong&gt; 協定就會自動關閉連線&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="使用-bash-測試"&gt;使用 bash 測試&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;span class="lnt"&gt;6
&lt;/span&gt;&lt;span class="lnt"&gt;7
&lt;/span&gt;&lt;span class="lnt"&gt;8
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 建立連線到 google&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;$ telnet google.com &lt;span class="m"&gt;80&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&amp;gt; Connected to google.com.
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&amp;gt; Escape character is &lt;span class="s1"&gt;&amp;#39;^]&amp;#39;&lt;/span&gt;.
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 發送 GET 請求&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;$ GET /about
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&amp;gt; ...
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;hr&gt;
&lt;h2 id="http10"&gt;HTTP/1.0&lt;/h2&gt;
&lt;h3 id="概要-1"&gt;概要&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;在 &lt;strong&gt;1991&lt;/strong&gt; 到 &lt;strong&gt;1995&lt;/strong&gt; 年之間，所謂 &lt;strong&gt;瀏覽器&lt;/strong&gt; 騰空出世！&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;於 &lt;strong&gt;1996&lt;/strong&gt; 年 &lt;strong&gt;5&lt;/strong&gt; 月發表 &lt;strong&gt;HTTP/1.0&lt;/strong&gt; 版 (&lt;a class="link" href="https://datatracker.ietf.org/doc/html/rfc1945" target="_blank" rel="noopener"
&gt;RFC 1945&lt;/a&gt;)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;與 &lt;strong&gt;HTTP/0.9&lt;/strong&gt; 不同的部分&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;用戶端要求是以 &lt;strong&gt;ASCII&lt;/strong&gt; 字元為主，但可發送多行命令(含要求標頭)
&lt;ul&gt;
&lt;li&gt;先送出&lt;strong&gt;要求方法&lt;/strong&gt;，再送出&lt;strong&gt;要求標頭&lt;/strong&gt;，最後以一個&lt;mark&gt;額外的換行字元&lt;/mark&gt;結束&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;伺服器回應是以 &lt;strong&gt;ASCII&lt;/strong&gt; 字元為主，回應內容會區分為
&lt;ul&gt;
&lt;li&gt;狀態列&lt;/li&gt;
&lt;li&gt;回應標頭&lt;/li&gt;
&lt;li&gt;回應內文主體(不僅僅是 &lt;strong&gt;HTML&lt;/strong&gt; 文件，可以是更多內容類型)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;每完成一次 Request / Response 交握就會&lt;strong&gt;自動關閉 TCP/IP 連線&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="使用-bash-測試-1"&gt;使用 bash 測試&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;span class="lnt"&gt;14
&lt;/span&gt;&lt;span class="lnt"&gt;15
&lt;/span&gt;&lt;span class="lnt"&gt;16
&lt;/span&gt;&lt;span class="lnt"&gt;17
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 建立連線到 google&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;$ telnet google.com &lt;span class="m"&gt;80&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&amp;gt; Trying 172.217.24.14...
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&amp;gt; Connected to google.com.
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&amp;gt; Escape character is &lt;span class="s1"&gt;&amp;#39;^]&amp;#39;&lt;/span&gt;.
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 發送 GET 請求&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;$ GET /about HTTP/1.0
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Host: www.google.com &lt;span class="c1"&gt;# 因一個 domain 可以 hosting 多個網站，因此通常都會於 request header 再標記 Host&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&amp;gt; HTTP/1.0 &lt;span class="m"&gt;301&lt;/span&gt; Moved Permanently
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&amp;gt; ...
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 取得後，會自動中斷 TCP 連線&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 若需再發送請求，需重新建立 TCP 連線&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;$ telnet google.com &lt;span class="m"&gt;80&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;...
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;hr&gt;
&lt;h2 id="http11"&gt;HTTP/1.1&lt;/h2&gt;
&lt;h3 id="概要-2"&gt;概要&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;於 &lt;strong&gt;1997&lt;/strong&gt; 年 &lt;strong&gt;1&lt;/strong&gt; 月發表 &lt;strong&gt;HTTP/1.1&lt;/strong&gt; 版 (&lt;a class="link" href="https://datatracker.ietf.org/doc/html/rfc1945" target="_blank" rel="noopener"
&gt;RFC 1945&lt;/a&gt;)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;於 &lt;strong&gt;1999&lt;/strong&gt; 年 &lt;strong&gt;6&lt;/strong&gt; 月發布 &lt;strong&gt;HTTP/1.1&lt;/strong&gt; 更新版 (&lt;a class="link" href="https://datatracker.ietf.org/doc/html/rfc2616" target="_blank" rel="noopener"
&gt;RFC 2616&lt;/a&gt;)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;與 &lt;strong&gt;HTTP/1.0&lt;/strong&gt; 不同的部分&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;傳輸協議的效能改進(新增不少 HTTP 標頭定義)
&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://en.wikipedia.org/wiki/HTTP_persistent_connection" target="_blank" rel="noopener"
&gt;持續連線狀態&lt;/a&gt;(persistent connection)&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://en.wikipedia.org/wiki/HTTP_chunked_encoding_transfer" target="_blank" rel="noopener"
&gt;切塊編碼傳輸&lt;/a&gt;(chunked encoding transfer)&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://en.wikipedia.org/wiki/HTTP_byte_range_request" target="_blank" rel="noopener"
&gt;位元範圍請求&lt;/a&gt;(byte range request)&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://en.wikipedia.org/wiki/HTTP_cache_control" target="_blank" rel="noopener"
&gt;額外快取機制&lt;/a&gt;(cache control)&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://en.wikipedia.org/wiki/HTTP_request_pipelining" target="_blank" rel="noopener"
&gt;請求管線作業&lt;/a&gt;(request pipelining)(需搭配&lt;strong&gt;持續連線狀態特性&lt;/strong&gt;才能用)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="使用-bash-測試-2"&gt;使用 bash 測試&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;span class="lnt"&gt;14
&lt;/span&gt;&lt;span class="lnt"&gt;15
&lt;/span&gt;&lt;span class="lnt"&gt;16
&lt;/span&gt;&lt;span class="lnt"&gt;17
&lt;/span&gt;&lt;span class="lnt"&gt;18
&lt;/span&gt;&lt;span class="lnt"&gt;19
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 建立連線到 google&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;$ telnet google.com &lt;span class="m"&gt;80&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&amp;gt; Trying 172.217.24.14...
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&amp;gt; Connected to google.com.
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&amp;gt; Escape character is &lt;span class="s1"&gt;&amp;#39;^]&amp;#39;&lt;/span&gt;.
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 發送 GET 請求&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;$ GET /about HTTP/1.1
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Host: www.google.com &lt;span class="c1"&gt;# 因一個 domain 可以 hosting 多個網站，因此通常都會於 request header 再標記 Host&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&amp;gt; HTTP/1.0 &lt;span class="m"&gt;301&lt;/span&gt; Moved Permanently
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&amp;gt; ...
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 取得後，不會自動中斷 TCP 連線，可再發送請求&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;$ GET /abc HTTP/1.1
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Host: www.google.com &lt;span class="c1"&gt;# 因一個 domain 可以 hosting 多個網站，因此通常都會於 request header 再標記 Host&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&amp;gt; HTTP/1.1 &lt;span class="m"&gt;404&lt;/span&gt; Page Not Found
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&amp;gt; ...
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h3 id="目前-http11-的六大規格"&gt;目前 HTTP/1.1 的六大規格&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://datatracker.ietf.org/doc/html/rfc7230" target="_blank" rel="noopener"
&gt;RFC 7230&lt;/a&gt; HTTP/1.1：Message Syntax and Routing&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://datatracker.ietf.org/doc/html/rfc7231" target="_blank" rel="noopener"
&gt;RFC 7231&lt;/a&gt; HTTP/1.1：Semantics and Content(最重要)&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://datatracker.ietf.org/doc/html/rfc7232" target="_blank" rel="noopener"
&gt;RFC 7232&lt;/a&gt; HTTP/1.1：Conditional Requests&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://datatracker.ietf.org/doc/html/rfc7233" target="_blank" rel="noopener"
&gt;RFC 7233&lt;/a&gt; HTTP/1.1：Range Requests&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://datatracker.ietf.org/doc/html/rfc7234" target="_blank" rel="noopener"
&gt;RFC 7234&lt;/a&gt; HTTP/1.1：Caching&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://datatracker.ietf.org/doc/html/rfc7235" target="_blank" rel="noopener"
&gt;RFC 7235&lt;/a&gt; HTTP/1.1：Authentication&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="關於-http-通訊協定的基本常識"&gt;關於 HTTP 通訊協定的基本常識&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;無狀態特性(stateless)：相同的 request，都會得到相同的 response，不會因為狀態不同而改變&lt;/li&gt;
&lt;li&gt;分散式架構(distributed)：相同的 request，不同載體發送，都會得到相同的 response&lt;/li&gt;
&lt;li&gt;協作的架構(collaborative)：不一定只有 client / server，也可以是 client / proxy / reverse proxy / server&lt;/li&gt;
&lt;li&gt;超文本(hypertext = not just &amp;ldquo;text) but with &amp;ldquo;links&amp;rdquo;)：除了內容，還包含連結&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="初學者應了解-http-的基本運作方式"&gt;初學者應了解 HTTP 的基本運作方式&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;如何發出 HTTP 要求(HTTP Request)&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;要求方法(Request Methods)
&lt;ul&gt;
&lt;li&gt;GET、POST、PUT、DELETE、PATCH、&amp;hellip;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;要求標頭(Request Headers)
&lt;ul&gt;
&lt;li&gt;Connection、COntent-Type、&amp;hellip;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;斷行符號(CRLF)&lt;/li&gt;
&lt;li&gt;要求內容主體(Request Body)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;如何回應 HTTP 訊息(HTTP Response)&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;回應狀態碼(Response Status Codes)
&lt;ul&gt;
&lt;li&gt;HTTP/1.1 &lt;code&gt;200&lt;/code&gt; OK&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;回應標頭(Response Headers)&lt;/li&gt;
&lt;li&gt;斷行符號(CRLF)&lt;/li&gt;
&lt;li&gt;回應內容主題(Response Body)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="http2"&gt;HTTP/2&lt;/h2&gt;
&lt;h3 id="http2-各個瀏覽器的支援度"&gt;HTTP/2 各個瀏覽器的支援度&lt;/h3&gt;
&lt;p&gt;&lt;a class="link" href="https://caniuse.com/?search=HTTP%2F2" target="_blank" rel="noopener"
&gt;點我查看瀏覽器支援度&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Edge / Firefox / Chrome / Opera 皆在 2015 年起就支援 HTTP/2，基本上不需要太擔心主流瀏覽器的支援性問題。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;PS：&lt;a class="link" href="https://hieven.medium.com/http-2-%E5%BE%9E%E9%9B%B6%E5%88%B0%E4%B8%80-be221087cd35" target="_blank" rel="noopener"
&gt;如何在 Node.js 中使用 HTTP/2&lt;/a&gt;&lt;/p&gt;&lt;/blockquote&gt;
&lt;h3 id="http2-改善了什麼"&gt;HTTP/2 改善了什麼？&lt;/h3&gt;
&lt;p&gt;http/2標準發布於2015年5月，其主要目的是透過一些措施改善瀏覽器瀏覽網頁 &lt;strong&gt;加載的速度(page load)&lt;/strong&gt; 。目前大多數的瀏覽器已支援 http/2 (chrome, firefox, safari等)標準，又 http/2與 http/1.1有著高度的相容信，舉凡request method(post, get..etc), http status code, url, header 等等，因此對於web developer來說，只需要確保你的網站有支援https(因為瀏覽器只支援https 在http/2上)。那麼http/1.1與http/2到底相差多快呢，&lt;a class="link" href="http://www.http2demo.io/" target="_blank" rel="noopener"
&gt;點我體驗&lt;/a&gt;!&lt;/p&gt;
&lt;h3 id="http2-是如何改善"&gt;HTTP/2 是如何改善？&lt;/h3&gt;
&lt;h4 id="只需要單一網路連線-single-tcp-connection"&gt;只需要單一網路連線 (Single TCP connection)&lt;/h4&gt;
&lt;p&gt;只需要單一網路連線，就可以連接網站伺服器，下載所有需要的資源。大大節省 HTTP/1.1 需要一直建立多個網路連線時的啟動時間浪費。&lt;/p&gt;
&lt;h4 id="request-and-response-multiplexing-多路複用"&gt;Request and response multiplexing (多路複用)&lt;/h4&gt;
&lt;p&gt;在 http/1.1 中，client 端時常會同時發起多個 request 至 server 拿取檔案(像是js, css, image等)，以此方式達到快速載入頁面。如下圖在 http/1.1 中會同時與 server 建立3個 TCP connection，但是瀏覽器通常會限制 TCP connection 同時建立的數目。因此在 http/2 協定中，允許 client 端與同一 server 建立單一 TCP connection 並以非同步方式傳輸要的檔案。&lt;/p&gt;
&lt;p&gt;&lt;img src="https://live.staticflickr.com/65535/52275827083_0a977870db_o.png"
max-width="100%"
max-height="100%"
class="gallery-image"
loading="lazy"
&gt;&lt;/p&gt;
&lt;h4 id="優先權設計-prioritization"&gt;優先權設計 (&lt;a class="link" href="https://nghttp2.org/blog/2014/04/27/how-dependency-based-prioritization-works/" target="_blank" rel="noopener"
&gt;Prioritization&lt;/a&gt;)&lt;/h4&gt;
&lt;p&gt;伺服器可以決定例如 CSS 或 JavaScript 檔案，哪些要優先傳送。&lt;/p&gt;
&lt;h4 id="header-compression-標頭壓縮"&gt;Header compression (標頭壓縮)&lt;/h4&gt;
&lt;p&gt;每一個 http 的傳輸中都會攜帶一組 header，在 http/1.1 中，header 會是以明文(plain text)傳輸大小通常會是500-800 bytes，若有攜帶 cookie 也有可能會更大。因此在 http/2 中，會將 request 以及 response 的 header 使用 &lt;a class="link" href="https://http2.github.io/http2-spec/compression.html" target="_blank" rel="noopener"
&gt;HPACK&lt;/a&gt; 演算法壓縮 header 的內容，此方法壓縮後可以減少 85%-88% 的大小。&lt;/p&gt;
&lt;h4 id="server-push-伺服器推送"&gt;Server push (伺服器推送)&lt;/h4&gt;
&lt;p&gt;在 http/1.1 中，通常 client 端 request 甚麼 server 就會回傳甚麼，例如: 當 client request html 那麼 server 將只會回傳 html。但在 http/2 中，允許 server 主動推送有相關的資料給 client，例如: 當 client 只 request html，但是 server 知道 client request 此 html 後續也會 request css, js 等，因此 server 就會在 client 沒有 request 的情況下主動推送 css, js 檔給 client。那 server 怎麼知道這些檔案是有相關性的呢? web developer 將需要 server push 的檔案加上特定的描述即可。(&lt;a class="link" href="https://www.smashingmagazine.com/2017/04/guide-http2-server-push/" target="_blank" rel="noopener"
&gt;描述&lt;/a&gt;)&lt;/p&gt;
&lt;p&gt;&lt;img src="https://live.staticflickr.com/65535/52274831682_c7dd69e454_o.png"
max-width="100%"
max-height="100%"
class="gallery-image"
loading="lazy"
&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;不過，這個功能比較有爭議，一來他需要 Web 開發者額外描述有哪些檔案需要隨著 HTML 一起推送給瀏覽器，不是 Web 伺服器升級 HTTP/2 就自動會有。二來它不管瀏覽器是不是已經有快取這個資源，都會推送而造成頻寬浪費。因此實務上筆者認為可以改用瀏覽器的 &lt;a class="link" href="https://css-tricks.com/prefetching-preloading-prebrowsing/" target="_blank" rel="noopener"
&gt;Prefetch&lt;/a&gt; 功能，讓客戶端的瀏覽器自己處理即可。&lt;/p&gt;&lt;/blockquote&gt;
&lt;h4 id="binary-framing-layer-二進制影格層"&gt;Binary framing layer (二進制影格層)&lt;/h4&gt;
&lt;p&gt;在 http/2 中，header 與 body 所挾帶的 property 與 http/1.1 相同(ex. verbs, methods)，然而兩者在傳輸上會有不同。在 http/2 中，會將 header 以及 body 編碼成二進制在 server 與 client 端中傳輸，在 http/1.1 中，則是以明文的方式傳輸。將訊息編碼成二進制進行傳輸，此特性是 http/2 的其他特性的根本基礎。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;冷知識：在 HTTP/1.1 定義了&lt;a class="link" href="https://www.w3.org/Protocols/rfc2616/rfc2616-sec4.html#sec4.4" target="_blank" rel="noopener"
&gt;四種解析訊息的方式&lt;/a&gt;，在 HTTP/2 只需要一種。&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;&lt;img src="https://live.staticflickr.com/65535/52274831672_3c70d84aab_o.png"
max-width="100%"
max-height="100%"
class="gallery-image"
loading="lazy"
&gt;&lt;/p&gt;
&lt;h3 id="總結"&gt;總結&lt;/h3&gt;
&lt;p&gt;根據 &lt;a class="link" href="https://w3techs.com/technologies/details/ce-http2" target="_blank" rel="noopener"
&gt;w3Techs&lt;/a&gt; 網站，目前使用http/2的網站有45.7%，未來確實會變成主流，身為軟體工程師，還是多少理解來的好。此篇文章僅記錄筆者蒐集資料彙整結果，若有任何錯誤資訊還請直接點出，萬分感謝。&lt;/p&gt;
&lt;hr&gt;</description></item></channel></rss>