全文為 HyperText Transfer Protocol,中文翻為「 超文本傳輸協定 」。
HTTP 就是一套網路傳輸協定,而今天要學的就是這套協定的內容是什麼,以及如何實作一個簡單的 Client 與 Server 端。要了解全球通訊網的基礎,才有辦法依照標準來實作網站。
一般來說傳輸資料的兩端會分為 客戶端 ( Client ) 跟 伺服器端 ( Server )
有沒有想過網頁上的資訊是怎麼來的,其實就是一大堆的 request 跟 response。
想要看到網頁上進行了哪些 request,可以打開瀏覽器的開發人員工具,切到 Network 標籤底下,再重新整理網頁,就可以看到 resquest 跟回傳的 response 詳細資訊。
快速開啟 safari 的開發人員工具 :
alt
+cmd
+I
全文為 Domain Name System
之前的章節也有介紹過 DNS,有興趣請看:[第一週] 搞懂目錄位置 & 網路基礎概論
當瀏覽器發送 request 的時候,其實是發送一個網址,但要怎麼知道網址的 IP 位置呢?就是靠 DNS 啦
以 HTTP的維基頁面為例,打開瀏覽器的開發人員工具,點開發送的 request ,可以看到有 url 跟 IP 位置 的資訊。
你也可以在 Terminal 查詢網域的 IP 位置,輸入
nslookup <要查詢的網域名稱>
前面有提過,其實瀏覽器幫我們做的就是:發送一堆 request、接收一堆 response,根據 html 裡面的內容再進行資源下載,而更詳細的 request 發送順序可以參考以下:
( 注意:這僅是目前理解的觀念,可能有誤,歡迎大家指正! )
.html
的 url其實沒有瀏覽器的情況下,我們也可以利用其他方式發送
request
跟 獲得response
。
以下是示範實做一個 Client 端發送 request。
利用 Node.js 的 library - request ( Simplified HTTP client ),模擬瀏覽器發送 request,步驟如下:
npm install request
const request = require('request');
request('http://www.google.com', function (error, response, body) {
console.error('error:', error);
console.log('statusCode:', response && response.statusCode);
console.log('body:', body);
});
現在假設我要發送一個 request 到此 blog 的首頁,所以把 URL 改成 blog 網址,再進行發送。
const request = require('request');
request('https://yakimhsu.com',
function (error, response, body) {
console.error('error:', error);
console.log('statusCode:', response && response.statusCode);
console.log('head:', response.headers); // 多印 response 的 header
console.log('body:', body);
});
執行後會得到以下的 response 內容:
process
模組process
是 Node.js 內建的模組,功能為「 取得指令的參數 」。
const process = require('process')
process.argv
node index.js 2
node
、 index.js
、 2
( 前面還會帶一些前綴字 )那在瀏覽器是怎麼顯示 response 資訊的呢?
我直接在 blog 首頁開啟開發人員工具,可以看到其實瀏覽器接收到的 response,跟我剛剛用 Node.js 收到的 response 是一樣的。
https://yakimhsu.com
的 request,收到的 response headerhttps://yakimhsu.com
,瀏覽器會發送一個此網址的 request,橘色框是收到的 response header( 只是瀏覽器幫你排版得比較好閱讀而已 )request
跟 response
的共通點都有 header 與 body,分別帶著不同資訊
而發送的 Request 根據不同的用途,有查詢、新增、修改或者是刪除,稱為「 Request Method 」,是為了讓 Server 能夠清楚辨別 request 的目的,而最常見的 Method 就是 Get
& Post
。
Get
單純的跟 server 要一個連結或圖片,通常網頁都是 Get 的 request 比較多
Post
需要執行一些動作時,會傳送 Post
的 request
Put
: 取代掉整個 requestPatch
: 修改部分 request ( 較推薦 )Delete
: 刪除資源Head
: 只要獲取 request 的 header,不要 bodyOption
: 可以暸解 server 提供哪些溝通方法用數字表示 response 的狀態,通常以開頭的數字做判斷。
1xx: 再等等
2xx: 成功了
3xx: 去其他地方
4xx: 你挫賽了( 客戶端 )
5xx: 我挫賽了( 伺服器端 )
100
Continue:Server 成功接收、但 Client 還要進行一些處理200
OK:成功204
No Content:成功,但沒有回傳的內容( 例如當你發出 Delete 的 request )301
Moved Permanently:資源「 永久 」移到其他位置,再下一次發出 request 時,瀏覽器會直接到新位置302
Found(Moved Temporarily):資源「 暫時 」移到其他位置304
Not Modified:東西跟之前長一樣,可以從快取拿就好400
Bad Request:請求語法錯誤、或資源太大…等等401
Unauthorized:未認證,可能需要登入或 Token403
Forbidden:沒有權限404
Not Found:找不到資源500
Internal Server Error:伺服器出錯,搶票時很可能發生501
Not Implemented502
Bad Gateway:通常是伺服器的某個服務沒有正確執行參考資料:
在這之前我們實作一個 Client 端,現在要來試試看 Server 端!
同樣也是利用 Node.js 內建 library : http
server.js
,輸入下列程式碼:let http = require('http'); // 引用 library: http
let server = http.createServer(handleRequest);
function handleRequest(req, res) {
console.log('request url: ', req.url);
if (req.url === '/') {
res.writeHead(200, { // 更改 response header
'info': 'index'
})
res.write('index'); // 更改 response body
res.end();
return;
}
if (req.url === '/redirect') {
res.writeHead(301, {
// 'Location': '/category' // 轉址到 /category
'Location': 'https://google.com' // 轉址到 google.com
});
res.end();
return;
}
if (req.url === '/category') {
res.writeHead(200, {
'info': 'category'
})
res.write('category')
res.end();
return;
}
res.writeHead(404);
res.end();
return;
}
server.listen(5000); // 監聽 5000 這個 port
node server.js
ctrl + C
停止http://localhost:5000
index
'/category'
category
'/redirect'
https://google.com
'/dakldf'
( 以上內容大部分是 程式導師實驗計畫第三期 的學習筆記,如有錯誤歡迎糾正,非常感謝 🤓 )
Written on May 6th, 2019 by Yakim shu