# [NET101] 網路基礎概論(搭配 JS 實作) ###### tags:`Frontend` [TOC] A、B 傳紙條,要完成遵守三個守則: 1. 寫明來源 1. 寫明目的地 1. 三個步驟來確認雙方訊息可以正常發送和接收: 「A 發送訊息給 B,B 接收到訊息,B 回傳訊息給 A,A 接收到訊息」 * B 接收到訊息 => B 接收 OK * B 回傳訊息給 A,A 接收到訊息 => A 發送 OK,A 接收 OK * B 回傳訊息給 A => B 發送 OK 標準化內容格式 分為 header(特殊需求), body(普遍需求) 用狀態碼標準化結果 用動詞(POST, GET, DELETE...)標準化動作 ## 協定 = 標準 = Protocol 當一件事情有了統一的標準,當很多人都遵守一個共同的標準,就可以把事情規模化 ## HTTP 協定 HTTP 負責前端和後端之間的溝通,request 和 response 傳的內容都是 "純文字",但從瀏覽器看的話,它會幫你把格式排版排好,所以具有可讀性。 ### DNS, Domain Name System 負責把 ==網址 Domain <=> IP address== 做查詢,但不一定都要向 DNS server 做查詢,也可以先在本地端的 ==cache== 做查詢,沒查詢到才去 DNS server 做查詢 `127.0.0.1` 是指 local host ### 永遠不要忘記瀏覽器只是另一個程式 request 和 response 不一定要用 browser 才可以做傳送和接收,脫離瀏覽器以後,同樣的事情還是可以做到瀏覽器在做的事情,例如 node 可以用 request library 來做 request 和 response 的處理。 ### Header 與 Body 每個 request 和 response 都有 header 和 body 存在,它們根據使用的 protocal 的種類,會有不同的格式,像是這一課使用的都是 http header ### HTTP Method 取得 request 和 response 的方法。 GET POST 可以放更多資訊,例如 cookies, 帳號, 密碼 DELETE PUT 覆蓋原本的內容 PATCH 增加新內容 [HTTP request methods](https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods) ### HTTP Status code * 301 資料永久移到別的位址,例如:傳一個`301`以及`網址從 a.com 移到 b.com`的資料,瀏覽器下次會從 b.com 直接找 DNS. * 302 資料暫時移到別的位址 #### cheat sheet 1** Hold on 2** Here you go 3** Go away 4** You fucked up 5** I fucked up 一些常見 status code: * 200 OK * 301 Moved Permanently (滾去其他地方) * 400 Bad Request (en-US) 伺服器因為收到無效語法,而無法理解請求。 * 404 Not Found [HTTP response status codes ](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status) ### 簡單 nodejs 實作 使用 'http' 這個 nodejs 內建 library 實作: ```javascript= var http = require('http') http.createServer((req, res) => { if (req.url === '/123') { console.log('123456') res.end() //才不會一直 pending return } if (req.url === '/redirect') { res.writeHead(200, { 'lidemy': 'good' }) res.end() return } if (req.url === '/goaway') { res.writeHead(302, { //302是轉址 'Location': 'https://www.pixiv.net/' }) res.end() return } else { res.writeHead(404) res.end() } }) server.listen(5000) //從 localhost:5000 監聽 ``` ## TCP/IP OSI 七層模型(OPEN SYSTEMS INTERCONNECTION MODEL): 總共7層,根據設備的address決定層 ![圖](https://www.practicalnetworking.net/wp-content/uploads/2016/01/packtrav-osi-layers.png) TCP/IP 基本上跟OSI模型一樣,只是分成4層,層與層之間是相互疊加的概念上的構造。 ### IP address IPv4(比較舊的 IP 格式)、IPv6(比較新的 IP 格式) 固定 IP,不會改變的 IP address,例如: server 浮動 IP,設備的 IP 每次都會改變 虛擬 IP,只存在於內網的 IP,內網與外網之間通過數據機的一個對外 IP 來溝通。 ### Port 的作用 電腦裡的 port 有很多個,每個 port 都有各自負責的服務,因此可以根據 port 來區別不同服務。例如預設進行特定服務的 port 有: HTTP:80 HTTPS:443 FTP:21 自己在作測試的時候通常會用 3000, 4000 port(沒什麼服務在使用的 port) ### TCP 與 UDP TCP,傳送 package 之後會**確認 (三次握手)**對方有收到,才會傳下一個封包,封包的傳送較可靠 ![三次握手](https://i.imgur.com/MU0Q3sa.png) UDP,不會確認對方有沒有收到封包,反正一直送封包過去就對了 ## 統整 ![總結](https://i.imgur.com/IUsajNL.png) (body, header 是在 HTTP 那一邊) ## API application programming **interface = 介面**,透過 API 可以讓雙方交換資料,例如: HTTP API 就是透過 HTTP 這個協定來交換資料。 串接 API 指的就是把 request 丟進去,然後拿到 respond (不太確定意思) ### 串接 HTTP API 實戰 ```javascript= const request = require('request') const process = require('process') const id = process.argv[2] //以 arr 的形式印出輸入 terminal 的程式碼 request.post( { url:'https://reqres.in/api/users', form: { 'name':'sasha', 'job':'hunter' } }, (error, response, body) => { console.log(body) } ) ``` ## 資料格式 XML 和 JSON 都是純文字的一種資料格式。 ### XML extensible markup language,==跟 HTML 依樣==,用 ==tag== 來標記內容的標記語言。 ### JSON * 使用 JSON.parse(//string) 把純文字轉換成 物件 * 使用 JSON.stringify(//obj) 把物件轉換成 純文字 ### 實作 ```javascript= const request = require('request') const process = require('process') const id = process.argv[2] //以 arr 的形式印出輸入 terminal 的程式碼 request.post( { url:'https://reqres.in/api/users', form: { 'name':'sasha', 'job':'hunter' } }, (error, response, body) => { console.log(body) //body 是一個 string (純文字) const json = JSON.parse(body) //把純文字的 string 轉換成 json 格式的物件 console.log(json) console.log(JSON.stringify(json)) //把物件轉換成純文字的 string } ) ``` ## HTTP API 以外的資料交換方式:soap 底層是透過 XML 來傳遞資料 ## RESTful 到底是什麼? 它不是一種格式,而是一種 ==API 命名風格==,==讓工程師可以簡單的一眼看出來== 網址<==>HTTP method 在腦中連接起來,例如: ![](https://i.imgur.com/nWYt8Q3.png) 畢竟同樣是"傳資料"這件事,用 PATCH, POST...都可以達成,如果大家都各自為政,使用自己喜歡的 HTTP method 來做同一件事情,這樣會有不好管理的問題 ## 好用工具 ### 必學指令:curl 會發 GET request 給某網址,然後拿回 response `curl '/網址' `//發 GET request 給某網址,然後印出 response `curl -I '/網址'` //只取出 header ### nslookup, ping, telnet `nslookup` 查詢 網址的 IP `telnet //ip 或網址 //port` 測試 port 有沒有開並連進去,沒有打 port 的話就會去預設的 23 port > win10 的 telnet 要自己去開起才可以使用,[開啟方法](https://goodlucky.pixnet.net/blog/post/48400569-%5Bwin10%5D-telnet-%E4%B8%8D%E6%98%AF%E5%86%85%E9%83%A8%E6%88%96%E5%A4%96%E9%83%A8%E5%91%BD%E4%BB%A4%E6%80%8E%E4%B9%88%E8%BE%A6%E5%91%A2%3F) ## query string 不同於 POST 會在 request 的 body 傳送額外資訊, query string 則是在網址裡面直接附上額外資訊的方法,query string 在 url 的格式是`?key=value` ![](https://i.imgur.com/QhSALVl.png) 如果 query string 的內容有特殊符號,就會讓對方的 server 不知道到底在傳甚麼資料,例如`str: "a&b=1"`,轉換成 query string 會是 `str=a&b=1`。 所以一般在 query string 的時候,都會先做 encode 的動作來避免這個問題,encode 可以用 JS 內建的`encodeURIComponent()`來達到 ```javascript= encodeURIComponent('a&b=1') // "a%26b%3D1" ```