---
# System prepended metadata

title: 一之 1 、 網之呼吸 - HTTP
tags: [Lidemy心得, JavaScript續, 進度筆記, 2020八月第二週, NET101]

---

# 一之 1 、 網之呼吸 - HTTP
###### tags: `NET101` `2020八月第二週` `進度筆記` `Lidemy心得` 8/9
---

HTTP 協定、標準，為了了解這個協定是甚麼，網頁前端跟後端溝通的時候就是透過 HTTP ， 是網際網路通訊的基礎，分成應用層、傳輸層、網路層和連結層，之後會提到。

參考資料:

[淺談網址 HTTP 與 HTTPS 的差別](https://www.webdesigns.com.tw/HTTPorHTTPS.asp)

[一文搞懂 HTTP 和 HTTPS 是什麼？兩者有什麼差別](https://tw.alphacamp.co/blog/http-https-difference)

[「筆記」- 何謂 HTTP 傳輸協定](https://medium.com/pierceshih/%E7%AD%86%E8%A8%98-%E4%BD%95%E8%AC%82-http-%E5%82%B3%E8%BC%B8%E5%8D%94%E5%AE%9A-1d9b5be3fd24)

[TCP/IP 協定與 Internet 網路：第十五章 全球資訊網系統](http://www.tsnien.idv.tw/Internet_WebBook/chap15/15-5%20HTTP%20%E5%82%B3%E8%BC%B8%E5%8D%94%E5%AE%9A.html)

---

# 一之 2 、 網之呼吸 - HTTP request
###### tags: `NET101` `JavaScript續` `2020八月第二週` `進度筆記` `Lidemy心得` 8/9
---

- HTTP request => Client request 請求 => Server response 。

以 GitHub https://github.com/Lidemy/mentor-program-4th 為例，在頁面後按下 F12 或 Ctrl+Shift+I 開啟網頁工具箱:  

![](https://i.imgur.com/TdKezNQ.png)  

- 在 Network 這一分頁會將瀏覽器所有 request (請求) 印出來 (如看不到要重新載入) ， 火狐跟 Chrome 的瀏覽器介面不太一樣。
- Headers 可以看到很多 request ; 而 Response (回應) 則是頁面的 html 。

整個網頁流程:

1. 瀏覽器 => 傳 HTTP request 至 server 。
2. Server 處理後 => 回傳一個 response ， 即:  

![](https://i.imgur.com/tdyeTNn.png)  

- 右邊回應內的這整段文字，只有瀏覽器看得懂。  
- 可以用 [Charles](https://www.charlesproxy.com/download/) 看 Request 和 Reponse 長甚麼樣子。   
- 用火狐的話可以省略安裝 Charles ， 在網路工具箱的檔頭內看到 Request 和 Reponse (請求檔頭和回應檔頭)。  
- GET https://github.com/Lidemy/mentor-program-4th ， GET 表示動作 ， http 表示指定地址，版本是 HTTP/1.1 ，通常會有 body ， 如果只是 GET ， 拿資訊，就不會看到 body 。  
- 在回應可以看到 [body](https://i.imgur.com/DyHtWBD.png) ， 許多的文字。
- request & response 都有一定格式。

---

參考資料:

[HTTP/1.1 — 訊息格式 (Message Format)](https://notfalse.net/39/http-message-format)  

---

# 一之 3 、 網之呼吸 - Domain Name System (DNS)
###### tags: `NET101` `JavaScript續` `2020八月第二週` `進度筆記` `Lidemy心得` 8/9
---

### 傳東西的話，理論上要看 IP 位置，但是 request 這只有要求網址:  

-  因此背後有機制將 https/Lidemy/mentor-program-4th (Domain Name) 轉成 IP 。
-  所以 Client 就會去問 DNS Server  ，  github.com 是在哪 ?  ~~我是誰 ? 我在哪 ?~~ 
``{"GET":{"scheme":"https","host":"github.com","filename":"/Lidemy/mentor-program-4th","remote":{"地址":"140.82.113.4:443"}}}``
-  實際上電腦最底層是把 request 送到 IP位置，可以看到 remote address 地址: 140.82.113.4:443 。
-  可以在 CLI 輸入指令 `nslookup github.com` 查詢 Domain Name ， 會得到:
 ```
未經授權的回答:
伺服器:  hitronhub.home
Address:  192.168.0.1

名稱:    github.com
Address:  140.82.112.3
 ```
---
參考資料:
[DNS 伺服器是什麼？如何運用？](https://www.stockfeel.com.tw/dns-%E4%BC%BA%E6%9C%8D%E5%99%A8%E6%98%AF%E4%BB%80%E9%BA%BC%EF%BC%9F%E5%A6%82%E4%BD%95%E9%81%8B%E7%94%A8%EF%BC%9F/)

---

### Host Database

- 假設電腦今天傳個 request 到 localhost ， 那電腦會先去 Host Database 查詢要傳到哪個 localhost 的 IP ， 優先配對規則 。

- 通常在測試的時候會用到 Host Database 的檔案，通常 localhost 就是代表自己的電腦(跑的服務) 。

---

# 一之 4 、 網之呼吸 - 瀏覽器概念
###### tags: `NET101` `JavaScript續` `2020八月第二週` `進度筆記` `Lidemy心得` 8/9
---

拜訪網頁時:
1. 瀏覽器幫 User 發 request 到 address。
2. 拿到 response 後呈現視覺渲染出來，成為看到頁面。
3. 根據回傳的 html 資訊下載資源，呈現文字、圖片、影片等。
---

## 拿拿看 response

但其實沒有瀏覽器的話，一樣可以拿到 response ， 在 node.js  內有個 library 就是 Request 可以去做這些事情。

https://www.npmjs.com/package/request

在有 npm ， node_modules 資料夾和 package.json 檔案的目錄下，安裝: `npm i request` ， 好了後可以新建一個 index.js 檔案直接使用下段 code :  
```
const request = require('request');
request('http://www.google.com', function (error, response, body) {
  console.error('error:', error); // Print the error if one occurred
  console.log('statusCode:', response && response.statusCode); // Print the response status code if a response was received
  console.log('body:', body); // Print the HTML for the Google homepage.
});
```

- 首先會將 request 給 require 進來 ， request 後面會接網址，可改成 https://github.com/Lidemy/mentor-program-4th 。
- 如果有 error 會將 error 印出。
- 如果沒有錯誤會將 statuscode 給印出。
- 可以先將 body 隱藏不印出。

執行 `node index.js` 會得到 ， response :  
error: null
statusCode: 200

沒有錯誤，請求成功。

---

## 印出 body 試試看
```
const request = require('request');
request(
  'https://github.com/Lidemy/mentor-program-4th',
  function (error, response, body) {
// console.error('error:', error); // Print the error if one occurred
// console.log('statusCode:', response && response.statusCode); // Print the response status code if a response was received
    console.log('body:', body); // Print the HTML for the Google homepage.
});
```
就會得到以 `<!DOCTYPE html>` 開頭的一大串組成 body 的 code 。

也因此可以自行轉成網頁，運用上面的 code ， 存成 index.js 檔案:  

```
const request = require('request');
request(
  'https://github.com/Lidemy/mentor-program-4th',
  function (error, response, body) {
// console.error('error:', error); // Print the error if one occurred
// console.log('statusCode:', response && response.statusCode); // Print the response status code if a response was received
    console.log('body:', body); // Print the HTML for the Google homepage.
});
```
使用以下指令:

- mac 似乎可以直接使用這個 `node index.js > github.html` 指令。
- win 的話可以用這 `env node index.js -i > github.html` 指令。

就會得到一個 github 的課綱頁面，https://github.com/Lidemy/mentor-program-4th 跟這個應該是一樣的。  
脫離瀏覽器後，我們可以發 request 到 server 去，自行寫 code 也可以 get 頁面。

---

參考資料:

[[Node.js]request](https://blog.johnsonlu.org/node-jsrequest/)

---

# 一之 5 、 網之呼吸 - Header 與 Body（不是網頁的那個）
###### tags: `NET101` `JavaScript續` `2020八月第二週` `進度筆記` `Lidemy心得` 8/10

- Header : 額外資訊。
- Body : 主要資訊。

---

而 request & response 都有 Header ， 分別帶有不同資訊。

先前是 request body ， 其實也能 request header :  

```
const request = require('request');
request(
  'https://github.com/Lidemy/mentor-program-4th',
  function (error, response, body) {
     console.log(response.headers)
});
```
可以看到內容有 date 時間 ， 'content-type' 表示是 html ， 編碼是 utf-8 ， server 是 GitHub.com 。

---
參考資料:
[解決 win 將 .js 檔案轉 html 的問題](https://superuser.com/questions/1011597/what-does-an-output-is-not-a-tty-error-mean)

---

# 一之 6 、 網之呼吸 - GET 與 POST
###### tags: `NET101` `JavaScript續` `2020八月第二週` `進度筆記` `Lidemy心得` 8/10

- GET 動詞表示動作，蠻常用到 GET 只是省略，幾乎很多 request 都是 GET 。
- POST 執行動作，登入頁面的時候會有，用網路工具箱去看 session 的 Headers 就會看到 Form Data ， 有 key:value ， 例如 login: 是帳號 ， password: 密碼。
- POST 內的 session 的 Headers ， Form Data  在 View source 的地方，表示在 request body 內其實是以 encode (不一樣的有不同規範) 形式:
![](https://i.imgur.com/T0ROxcX.png)

---

# 一之 7 、 網之呼吸 - HTTP other method
###### tags: `NET101` `JavaScript續` `2020八月第二週` `進度筆記` `Lidemy心得` 8/10

- 常用的動作有: GET 、 PUT 、 POST 、 DELETE 。
- 可以參考  [MDN HTTP 請求方法](https://developer.mozilla.org/zh-TW/docs/Web/HTTP/Methods)
- PUT 和 PATCH 有點類似，但 PUT 會更新狀態資訊。
- 例如用 PUT 雞腿飯*3 ，會把原本訂購雞腿飯*2 和排骨飯*5 ，直接修成雞腿飯*3 ， 排骨飯就消失了。
- PATCH 則是會讓原本訂購的排骨飯存在，這個比較不會蓋掉所有東西。
- OPTIONS 會讓 server 回傳給你，這 server 支援甚麼方法。

---

# 一之 8 、 網之呼吸 - HTTP status code
###### tags: `NET101` `JavaScript續` `2020八月第二週` `進度筆記` `Lidemy心得` 8/10

狀態代碼 (status code) ， 參考 [MDN 網路狀態代碼](https://developer.mozilla.org/zh-TW/docs/Web/HTTP/Status) ， 以開頭為區分。  
- 1. 開頭 Client 端需要處理，少見。  
- 2. 開頭，常見的 200 代表成功居多 ， 204 表示刪除資源成功，但是沒有資訊要傳達。  
- 3. 開頭，像是 301 這東西永久被移到新位置，而 302 可能是暫時移到新位置。  
```
今天第一次訪問某個網址得到:
GET aaaaa.com
但 aaaaa.com server response:
statust code: 301
Location: b.com

然後下一次再去 aaaaa.com
瀏覽器 (有存 cookie) 會從第一次訪望這個網址後得知，
該網址被永久移到 b.com ， 因此會自動移過去。

GET aaaaa.com => b.com(瀏覽器幫你自動移形換位)
就像餐廳永久遷址一樣。
---------------------------------------------------------------------------

但如果是這樣子得到 (暫時的移動到 b.com) :
GET aaaaa.com
但 aaaaa.com server response:
statust code: 302
Location: b.com

瀏覽器還是會去 aaaaa.com ， 然後再問一次我要去哪 ?
瀏覽器才會再去 b.com 。
像是餐廳暫停營業，暫時遷址到其他地方，所以我下次再來還是原店舊址。
```
- 4. Client 端出了錯誤，像是 400 語法錯誤，要的東西太多; 或是常見的 404 Not Found ， 要的東西餐廳沒有提供。  
- 5. Server 端錯誤，像是搶票的時候會看到 500 ， 503 Server overload ， 因此要維修。   

![](https://i.imgur.com/2LP3TIT.png)  

---

# 一之 9 、 網之呼吸 - 實作簡易 HTTP Server
###### tags: `NET101` `JavaScript續` `2020八月第二週` `進度筆記` `Lidemy心得` 8/10

- 之前有實作 Client 端，用 npm library 的 request 去 request body 。  

__這次也用 node.js 的內建 library HTTP 來實作，以下 code 存成 server.js 檔案:__
```
var http = require('http')

var server = http.createServer(handleRequest)
function handleRequest(req, res) {
  console.log(req.url)
  res.write('Hello !')
  res.end()
}
//可以這樣寫 var server = http.createServer(function(req, res) {})，不習慣可用↑
 
server.listen(5000) // 服務代碼 port;
```
- 執行指令 `node server.js` 因為 req.url 沒有指明位置，所以只會看到程式 (server) 一直在跑，按下 Ctrl+c 中斷，實際上 server 端也是要全天候運作。  

- 如果讓 CLI 下的指令 `node server.js` 持續在跑的情況，再去瀏覽器網址列輸入 `localhost:5000/` 會看到瀏覽器印出 Hello ! 。  

- 同時看到 CLI 的介面會出現:
```
/
/favicon.ico
```
- 1. 第一個 / 是根目錄，可以看到 localhost 。
- 2. 第二個 .ico 是瀏覽器分頁左上的小 icon ， 通常會顯示在分頁上，瀏覽器通常預設會去拿。
![](https://i.imgur.com/wSGRUl7.png)
- 3. 也可以在 / 根目錄拜訪不同的 slash ， 例如 /Hello! ， 在瀏覽器開啟網路工具箱 => Network 會看到 localhost 名字變成 Hello! 。

- 如果關掉指令 `node server.js`  ， 瀏覽器也重新整理，網路工具箱 => Network 就會沒有反應，因已經沒有服務在聽 5000 這個 port 。

---

## 根據 req.url 做不同事情
可以根據 req.url 做不同事情:  
```
var http = require('http')

var server = http.createServer(handleRequest)
function handleRequest(req, res) {
// console.log(req.url)
    if (req.url === '/') {
      res.write('Welcome !')
      res.end()	
      return
    }

    if (req.url === '/Hello') {
      res.write('Hello !')
      res.end()	
      return
    }

    if (req.url === 'redirect') {

  }

}
//可以這樣寫 var server = http.createServer(function(req, res) {})，不習慣可用↑
 
server.listen(5000) // 服務代碼 port;
```
然後進行指令 `node server.js` ， 再去瀏覽器網址列輸入 `localhost:5000/` 會看到以下狀況:  
- 只有在 / 的情況，文字被替換成 Welcome ! 。  
- Server 端會根據不同 / 底下的網址輸入給出不同回應。  
- 如果在瀏覽器網址列輸入 /Hello ， 會看到印出 Hello ! 。

---

## 運用重新導向
### 狀態代碼 200 的情況:
```
var http = require('http')

var server = http.createServer(handleRequest)
function handleRequest(req, res) {
// console.log(req.url)
    if (req.url === '/') {
      res.write('Welcome !')
      res.end()	
      return
    }

    if (req.url === '/Hello') {
      res.write('Hello !')
      res.end()	
      return
    }

    if (req.url === '/redirect') {
      res.writeHead(200, {
        'lidemy': 'good'
      })
     res.end()	
      return
  }
  res.writeHead('404')
  res.end()	
  return
 }
//可以這樣寫 var server = http.createServer(function(req, res) {})，不習慣可用↑
 
server.listen(5000) // 服務代碼 port;
```
- 在瀏覽器輸入 / 或是 會跟之前一樣，而網路工具箱下顯示服務狀態代碼則是 200 。  
- 而在 / 後隨便打個 ppap 還是甚麼，就會出現狀態代碼 404 。  
- 而在 /redirect 則會看到網路工具箱內，檔案下 redirect 顯示 200 ，右邊的檔頭內，回應檔頭 (Response Headers) 則有 lidemy	good 訊息。  

### 狀態代碼 302 的狀況:  
狀態代碼 200 的情況:
```
var http = require('http')

var server = http.createServer(handleRequest)
function handleRequest(req, res) {
// console.log(req.url)
    if (req.url === '/') {
      res.write('Welcome !')
      res.end()	
      return
    }

    if (req.url === '/Hello') {
      res.write('Hello !')
      res.end()	
      return
    }

    if (req.url === '/redirect') {
      res.writeHead(302, {
        'Location': '/Hello'
      })
     res.end()	
      return
  }
  res.writeHead('404')
  res.end()	
  return
 }
//可以這樣寫 var server = http.createServer(function(req, res) {})，不習慣可用↑
 
server.listen(5000) // 服務代碼 port;
```
-   /redirec 下如果狀態代碼 302 ， 則要選擇要轉到哪個 / 底下:
```
   if (req.url === '/redirect') {
      res.writeHead(302, {
        'Location': '/Hello'
```
- 網路工具箱內會先顯示狀態代碼 302 ， 然後告訴你轉去 /Hello 底下，再顯示 200 。

---

# 一之 10 、 網之呼吸 - 總結
###### tags: `NET101` `JavaScript續` `2020八月第二週` `進度筆記` `Lidemy心得` 8/11

- HTTP 協定。
- 瀏覽器程式的限制，不是 HTTP 或是 Server 本身的限制。
- 實作 request 和 server ， 寫程式也能達到瀏覽器效果。

---