# [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決定層

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 之後會**確認 (三次握手)**對方有收到,才會傳下一個封包,封包的傳送較可靠

UDP,不會確認對方有沒有收到封包,反正一直送封包過去就對了
## 統整

(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 在腦中連接起來,例如:

畢竟同樣是"傳資料"這件事,用 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`

如果 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"
```