# 網路基礎概論 ─ 重點整理
## 為什麼需要通訊協定(protocol)?
請先想像一下,不同國家的人一起坐在一場圓桌會議上,有些人說日文、有些人說英文、有些人說中文,大家雞同鴨講,無法順利溝通。這時候就可以使用一個語言,是大家都會的語言,這樣的語言就像是 protocol。
Protocol 就像是是一個格式化的標準,讓不同規格、不同語言、不同系統的系統或是平台,都能透過這樣的標準,進行資訊的流通及處理。
舉例來說,要瀏覽網站的話,要遵守網站的通訊協定,叫 http ( HyperText Transfer Protocol );而要傳輸檔案,則要遵循傳輸檔案用的 FTP ( File Transfer Protocol )。
## HTTP ( 超文本傳輸協定 )
### 概要
了解網站前,先要知道網站的資訊是如何傳送的。Client 端( ex:是瀏覽器)發送HTTP Request (包含 head 跟 body)請求給 Server 端,Server 端收到後再回傳 Response 回應(包含 head 跟 body)給 Client 端。[詳請可看此。](https://medium.com/@justinlee_78563/%E9%97%9C%E6%96%BCweb%E5%BE%8C%E7%AB%AF-1-%E4%BB%80%E9%BA%BC%E6%98%AFweb-server-83ee32bc7d3e)
### 如何詳細看到資訊傳送的流程
1. 按 F12 打開開發者工具。
2. 點擊 Network 標籤,即可看到所有瀏覽器發送的所有 Request 跟 Response ( html 標籤)。
3. Request 跟 Response 都要按照既定模式才可以傳送成功。
### DNS Server ( Domain Name System )
將 Domain Name 網域名稱(www.google.com)翻譯成 IP 位址。
在 terminal 上可以使用 `nslookup` 的指令,後面加上欲查詢 IP 位址的網域名稱,即可查詢 IP 位址。如果查詢結果是 no response from server 時,可以在 Terminal 上使用 `netsh winsock reset`,再重啟電腦一次,即可順利使用 `nslookup` 指令。
### 瀏覽器只是幫助我們協作的程式
瀏覽器是協助我們發送 request ,接收 response 的程式。透過 node.js 的 library ─ [request](https://github.com/request/request) ( Simplified HTTP client ),也可以模擬瀏覽器發送 request,步驟如下:
1. 先在 terminal cd 到專案資料夾,並輸入 `npm install reqest`指令。
2. 下載後先新增一個 js 檔案,並在檔案內貼上官網提供的程式碼。這個動作是為了實作發送 request 。
當中的網域名稱可自由更換到自己欲實作的網頁網域。
```javascript=
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.
});
```
3. 執行`node index.js > index.html`,將 console.log 出來的 response 寫入 index.html 內。
4. 執行 `index.html`(打開此檔案),即可順利看到最後結果。
### header 跟 body
request 跟 response 內都有包含 header 跟body。 header 寫的是一些額外資訊, body 寫的是主要內容。
### HTTP 請求方法
詳細更多可以參考 [MDN](https://developer.mozilla.org/zh-TW/docs/Web/HTTP/Methods)。
#### get
索取並顯示資訊。如顯示圖片或 html 及 css。
透過 dev tool 內可以看到 request URL。複製此 URL 並另開一個分頁去執行,所看到的畫面,就是 response。而這個背後程式所做的事情,就是瀏覽器發送了一個 get request 到這個 URL,並接收到了 response。
#### post
提交資料並請求伺服器處理。如輸入帳號密碼。
特別注意的是,get request 沒有 body, post 有。
#### put
更改並取代原先資料。
假設今天原訂單是雞腿飯 3,排骨飯 5,put 雞腿飯 2,那這樣最後的訂單會是雞腿飯 2,連排骨飯 5 都會不見。
#### patch
更改指定資料。
假設今天原訂單是雞腿飯 3,排骨飯 5,patch 雞腿飯 2,那這樣最後的訂單會是雞腿飯 2,排骨飯 5,排骨飯 5 會被保留下來。
#### delete
刪除資料。
#### option
回傳該 server 可支援的溝通方式。
### HTTP 狀態碼 Status Code
1. **1XX ─ 1 開頭的狀態碼:你等等 (client 端需要做一些處理)**。
3. **2XX ─ 2 開頭的狀態碼:成功**。
200 OK 就是完全順利成功
204 No Content 就是成功但沒有回傳任何訊息(使用 delete 時)。
3. **3XX ─ 3 開頭的狀態碼:去其他地方(重新導向)**。
301 Moved Permanently :就是這個網域永久的被移到其他位置,下次再度使用 get 時,會直接導向另一個網域。
302 Found(Moved Temporarily):是暫時被移到其他位置,下次使用 get 時,一樣會導到此網域。
304 Not Modified:東西跟之前長一樣,可以從快取拿就好。
4. **4XX ─ 4 開頭的狀態碼:你慘了(client 端錯誤)**。
400 Bad Request:請求語法錯誤、或資源太大…等等。
401 Unauthorized:未認證,可能需要登入。
403 Forbidden:沒有權限。
404 Not Found:找不到資源。
408 Request Timeout : 請求超時。可再隨時提交一次請求且無須修改。
5. **5XX ─ 5 開頭的狀態碼:我慘了(server 端錯誤)**。
500 Internal Server Error:通用的伺服器出錯。(搶票時常見)
503 Service Unavailable:伺服器暫時無法處理。
更多請看[維基百科](https://zh.wikipedia.org/wiki/HTTP%E7%8A%B6%E6%80%81%E7%A0%81),想看有趣版可以[點此](https://noob.tw/http-status-code/)。
### 實作 server 端
透過 node.js 內的 library ─ `http` 實作 server 端。
1. 新增一個 server.js 檔案,並輸入以下內容。
```javascript=
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('content'); // 更改 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 === '/hello') {
res.writeHead(200, {
'info':('hello')
})
res.write('hello')
res.end()
return;
}
res.write(404);
res.end();
return;
}
server.listen(5000); // 監聽 5000 這個 port
```
2. 執行`node server.js` 指令(執行 server)
3. server 會不斷的執行直到按下 Ctrl + c
驗證是否可以傳到 client 端:
1. 打開瀏覽器的新分頁,並輸入 http://localhost:5000,應該會看到畫面上出現 content。
2. 輸入 http://localhost:5000/hello ,畫面會出現 hello。
3. 輸入 http://localhost:5000/redirect ,畫面會跳轉到 www.google.com 。
4. 隨意輸入 http://localhost:5000/djioejfo ,畫面會出現無法連上這個網站(404 not found)。
## TCP / IP
TCP / IP 是電腦網路通訊協定,分成四個層級( 應用層、傳送層、網路層、鏈結層 )。更詳細可參考[鳥哥的私房菜](http://linux.vbird.org/linux_server/0110network_basic.php)。
![](https://i.imgur.com/ZSQxJCe.png)
圖片來源:鳥哥的私房菜
從這個協定當中可以看到 HTTP 協定〈應用層〉建立在 TCP 協定〈傳送層〉上,而 TCP 協定又建立在 IP 位址〈網路層〉上。
### IP 地址( Internet Protocol )
IP 全名為 Internet Protocol,中文為「 網際網路協定 」。
協定也有分版本,分別是 IPv4(Internet Protocol version 4) 跟 IPv6(Internet Protocol version 6)。IPv6 可用的地址更多,解決主要 IPV4 不夠用的問題,兩者的地址也完全不同。更多差異請[看這](https://www.ithome.com.tw/tech/92046)。
IP 也有分成**固定 IP、虛擬 IP、浮動 IP**。
1. **固定 IP**:每一台電腦都有一個 IP 位置(理想狀態下),這 IP 位置是固定的,費用也較高。而基本上伺服器都跟公司企業是用固定 IP,這樣才能保證使用者可以連上伺服器,不會突然找不到。
2. **虛擬 IP**:大公司內常常會需要因為資安因素,以連上同一個類似數據機的電腦設定虛擬 IP,避免將資料帶離公司,或者是防止駭客入侵。這些虛擬 IP 只有在內網才可以互相連接,對外一律都是同一個 IP 位置(有可能是固定 IP 或浮動 IP)。詳見下圖。
![](https://i.imgur.com/0hjSHuI.png)
圖片來源:Huli 課程內容
這樣改變位址的數據機我們稱為 NAT,底下會在更仔細的討論 。
3. **浮動 IP**:許多一般及家用戶都是浮動 IP,IP 位址會隨著每次連線而改變,好處是電信公司不需要直接給一個固定 IP,也因為浮動的 IP 位址不易受到駭客攻擊。
想要查詢自己對外的 IP 位址,可以使用「 myip 」作為關鍵字,許多網頁都有提供這樣的服務使用。
### NAT
> NAT,Network Address Translation,網路位址轉譯。
剛開始是為了解決 IPv4 位址不夠的的問題,而想出的一個過渡期解決辦法。目前主要的用途是有三:
1. 封包偽裝(IP masquerade)
* 改變私有 IP(內部 IP)改變成真實 IP(外部 IP)再傳送到網際網路。也就是我們前面提到的功能。
* 讓其他人不知道內部到底有幾個伺服器及 IP 分配情形而增加網路安全性。
2. 封包過濾
* 可以攔截網際網路進入私有網路的封包,阻擋怪客(Cracker)的攻擊。
* 因上述,NAT 是最重要的防火牆成員,也是一種「封包過濾器(Packet filter)。
3. 負載平衡(Load Balance)
* 通常使用在 web server,一般網頁可能同時會有很多人連線到伺服器,單一台主機(伺服器)沒有辦法負荷這麼多的連線請求,這時候就可以透過前面說的封包偽裝的特性,更改 IP 位址後發送到不同的主機,藉此減輕單一主機的負擔,同時增加網路安全性。
備註:其實有個東西叫做[負載平衡器](https://zh.wikipedia.org/wiki/%E8%B4%9F%E8%BD%BD%E5%9D%87%E8%A1%A1)(Load Balancer),是一個軟體程式,主要就是在負責 load balance,詳細可參考 [文章一](https://akuma1.pixnet.net/blog/post/168326978-%E5%A4%A7%E6%9E%B6%E6%A7%8B%E7%9A%84%E6%A6%82%E5%BF%B5%E8%88%87%E7%A8%8B%E5%BC%8F%E8%A8%AD%E8%A8%88%EF%BC%8D%EF%BC%8D%EF%BC%88%E4%B8%89%EF%BC%89load-balance) 及 [文章二](https://wiki.mbalib.com/zh-tw/%E8%B4%9F%E8%BD%BD%E5%B9%B3%E8%A1%A1)
[資料來源](https://www.stockfeel.com.tw/nat-%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/)
### Port 連接埠( 端口 )
為了區分並接收同個電腦( IP 位址 )的不同服務,所以就有了 Port 。 在剛剛的實作一個 server 端所輸入的`server.listen(5000);`,這邊的 5000 就是一個 port。
預設的 port 有 HTTP (80)、HTTPS (443)、FTP (21)。常見的測試值為 3000、4000、4001。
### TCP 與 UDP
TCP 與 UDP 都是傳送層中的兩個協議。
大部分的網路協定都是建立在 TCP 上,因為 TCP 較為可靠、會透過「**三次握手**」確保資料送達。
而 UDP 重點在於速度,在日常網路應用上像是視訊或是轉播時,重點在於傳送速度而不是傳送穩定,因為漏了一兩個封包其實對使用者並不會有明顯的影響。
**何謂三次握手**?
> 三次握手又稱三路握手,全名為 threee-way handshake。簡單來說 client 端跟 server 端會通過三次的聯繫來確保資訊有確實傳達給對方。
![](https://i.imgur.com/7WVAE4q.png)
圖片來源:由 原上傳者為中文維基百科的Huage.chen - Transferred from zh.wikipedia to Commons by Shizhao using CommonsHelper., CC BY-SA 3.0, https://commons.wikimedia.org/w/index.php?curid=36967543
### 總結
| 層級內容 | 層級用義 | 紙條故事 |
| -------- | ------ | --------|
| HTTP / FTP| 傳輸內容 | 紙條內容 |
| TCP / UDP | 傳輸方式 | 三次確認 / 講求速度 |
| IP | 傳輸地址 | 寄件人和收件人|
| 實體層 | 實體傳輸 | 郵差 |
## Server 伺服器
這裡的伺服器**並非**指的是像 Apache(Web Server)、FTP Server 這類管理伺服器的軟體。
這裡的伺服器指的是執行上述各種伺服器管理軟體的主機,伺服器管理軟體可能還包含 DNS Server、Mail Server、Database Server 等。通常具備較高的計算能力、能夠提供給一個或多個使用者使用的電腦/主機。
### 種類
伺服器常見有三個種類:
1. 虛擬空間
* 只有空間而已,沒有操控權
2. 虛擬主機
* 一台實體主機上面有很多虛擬主機,可以視為 cloud
* 如果共用的實體主機壞了,可以自由且無痛遷移至另一個實體主機
* 需和其他虛擬主機共享 CPU 、記憶體等實體主機的硬體效能。
3. 實體主機
* 自己有一台完整的主機
* 主機壞了裡面的資料也會完全損毀,難以修復
### 管理
常見管理的方式有兩種:
1. 遠端連線:一般較常見在 window 系統,可能會使用 Microsoft 為 Windows 10 所免費推出的遠端伺服器管理工具(Remote Server Administration Tools,RSAT),或者是其他第三方工具:像是 Team Viewer、VNC。
2. SSH
* 全名為 Secure Shell Protocol,安全的殼程式協定,提供類似 telnet 但更安全的遠端連線。
* 透過 command line 介面直接連到遠端的主機下指令,通常是打 `ssh + ip位址` ,連線成功後可以使用 `top` 確認主機效能。
* 最常見、普遍的管理方式。
## VPN
> Virtual Private Network,虛擬私人網路。根據維基百科,VPN 是一種常用於連接中、大型企業或團體與團體間的私人網路的通訊方法。 它利用隧道協定(Tunneling Protocol)來達到傳送端認證、訊息保密與準確性等功能。
概念基本上就像是先連到一個主機,再由那個主機連線到其他地方。常見的應用:
* 公司內網:先連到公司內網才能存取公司的資料。
* 使用學校服務:同理,連到學校內部才能使用學校資料
* 翻牆
## API
> 全名為 Application Programming Interface,中文翻譯為「應用程式介面」。簡單來說透過 API 就是一個交換資料的工具。
API 有分很多種,這邊會提到的是基於 HTTP 協定下的 Web API (HTTP API)。
API 常見的 CRUD 功能分別指的是:新增(Create)、讀取(Read)、更新(Update)、刪除(Delete),有時候會聽到五項功能,多了一個列表(List)。
### 如何串接 API
#### 方法一
有個簡單提供測試是否可以串接成功的 API 網站 ─ [Regres](https://reqres.in/)。透過此網站下方 jQuery 內提供的 URL,放入測試程式碼內,即可實測。
```javascript=
const request = require('request');
request('https://reqres.in/api/users', function (error, response, body) {
console.log( body); // Print the HTML for the Google homepage.
});
```
在 URL 後方也可以加上欲加入的物件,像是https://reqres.in/api/users/2, 即可呈現 ID :2 的元素。
若是想要在 Terminal 上直接執行 `node index.js 2` ,可以另外在檔案內加入`const process = require('process');`,並可以先用`console.log`測試 process 到底是甚麼。
在 terminal 上執行 `node index.js 2`,就會發現顯示出來的結果是。
![](https://i.imgur.com/g5oHvad.jpg)
第一行顯示的結果表示,node 位置。
第二行顯示的結果表示,index.js 位置。
第三行顯示的結果表示,2。
process.argv[2] 作為一個陣列,欲取第三個元素。並將此放在 URL 後。範例碼如下:
```javascript=
const request = require('request');
const process = require('process');
request(
'https://reqres.in/api/users/' + process.argv[2],
function (error, response, body) {
console.log(body);
}
);
```
這時候如果在 Terminal 內中執行 `node index.js 2`,即可順利顯示 ID 2 的內容,執行 `node index.js 3`,也可順利顯示 ID 3 的內容。
#### 方法二
透過之前有提到的 request library 的[ Github 網頁](https://github.com/request/request#forms),點選 forms,並使用之前所提到的[ reqres ](https://reqres.in/)將相關資料填入。
```javascript=
const request = require('request');
const process = require('process');
request.post(
{
url:"https://reqres.in/api/users",
form: {
name:'shelly',
job: 'none'
}
},
function (error, response, body) {
console.log(body);
}
);
```
執行 `node index.js ` 也可成功寫入資料(這邊只是測試用,所以並不會真正寫入資料)。
### 實測串接 API
該如何實際執行 API 的 GET、POST、PATCH、DELETE...等指令呢?可以透過之前提到的[ request 官方文件](https://github.com/request/request),並 ctrl + F 找關鍵字「request.METHOD()」,找到如何使用的方法。
以下實作 DELETE 跟 PUT。
#### DELETE
依照官網在所提供的語法(`request.delete`),以下提供範本。
```javascript=
const request = require('request');
const process = require('process');
request.delete(
"https://reqres.in/api/users/2",
function (error, response, body) {
const json = JSON.parse(body);
console.log(json);
}
);
```
執行後會發現沒跑出任何 response。這時候我們可以在第六、七行之間加上`console.log('body:', body)`,確認 body 內容。執行後發現 body 是空的。
這時候我們可以再透過印出 status code 確認狀態。透過`console.log(response.statusCode)`回傳的結果是 204 。表示是成功的,只是沒有內容(因為已經刪除完畢)。
#### PATCH
與 POST 運用的格式相同,範例如下:
```javascript=
const request = require('request');
const process = require('process');
request.patch(
{
url:'https://reqres.in/api/users',
form: {
Name:'Shell'
}
},
function (error, response, body) {
console.log(body);
}
);
```
### RESTful API
RESTful 是一種風格,該如何形容這個風格呢?就是一種語意化、更為嚴謹的描述 API 方式,目前也是最常見的方式。
![](https://i.imgur.com/SYoumdT.jpg)
本圖片源自 Huli 上課教材。
在最左邊的一欄當中是要做的事情,左二是欲使用的指令,取而代之咖啡色字體的是 RESTful 風格的指令,右二是非 RESTful 風格的寫法,右一是 RESTful 風格的寫法。
所以可以看到 RESTful 的寫法較為一致、也更好理解。
[這篇簡報](https://github.com/TritonHo/slides/blob/master/Taipei%202016-04%20talk/RESTful%20API%20Design-tw-2.1.pdf)有更仔細地談甚麼是 RESTful API。
## 資料格式
之前我們提到的發送或是回傳的資料,都是有格式的。這些在電腦科學中,資料格式是電腦中儲存、傳輸資料的方式。
資料格式可以簡略分成三種:純文字與自定義格式、XML、JSON。
### 純文字與自定義格式
> 直接透過文字跟條件式定義格式。
### XML
> 全名是 Extensible Markup Language,中文是可延伸性標記式語言。XML 跟 HTML 一樣,都是屬於 Markup Language 標記式語言,均透過前後的標籤來包覆住內容。這裡可參考更多[ XML ](https://support.office.com/zh-tw/article/xml-%E5%85%A5%E9%96%80-a87d234d-4c2e-4409-9cbc-45e4eb857d44)入門文件。
以前傳輸資料經常使用 XML,現在多數人都使使用 JSON。
### JSON
> 全名是 JavaScript Object Notation ,中文是 JavaScript 物件表示法。依照維基百科,是一種輕量級的資料交換語言,該語言以易於讓人閱讀的文字為基礎,用來傳輸由屬性值或者序列性的值組成的資料物件。
雖然 JSON 稱之為 JavaScript 物件表示法,但是這個資料格式被廣泛的以函式庫的方式,用在其他語言當中。
JSON 所需要的儲存空間相較 XML 少上許多,所以**目前 JSON 是最普遍被使用的資料格式。**
在程式判讀上 XML 相較另一個資料格式 JSON 需要花費更多時間耗費資源。更多兩個資料格式的比較,可以看[ JSON與XML優缺點對比分析 ](https://codertw.com/%E5%89%8D%E7%AB%AF%E9%96%8B%E7%99%BC/276753/)。
#### 實作 JSON
之前實作 API 時所回傳的格式,就是 JSON 格式。
```javascript=
const request = require('request');
const process = require('process');
request(
"https://reqres.in/api/users/2",
function (error, response, body) {
console.log(body);
}
);
```
回傳的 response 如以下:
```javascript=
{"data":{"id":2,"email":"janet.weaver@reqres.in","first_name":"Janet","last_name":"Weaver","avatar":"https://s3.amazonaws.com/uifaces/faces/twitter/josephstein/128.jpg"}}
```
這個回傳的格式,就是一個 JSON 格式的 string。這樣的 String 比較難像物件一樣直接存取物件的 key 。那我們可以透過內建函式`JSON.parse()`,**將 string 改成物件格式。**
將上面的`console.log(body)`改成`console.log(JSON.parse(body))`。回傳的 response 則會變成以下:
```javascript=
{ data:
{ id: 2,
email: 'janet.weaver@reqres.in',
first_name: 'Janet',
last_name: 'Weaver',
avatar:
'https://s3.amazonaws.com/uifaces/faces/twitter/josephstein/128.jpg' } }
```
那如果是物件格式想要改成 JSON 格式的 string ,可以使用 `JSON.stringify()`。
## SOAP
> SOAP 全名為 Simple Object Access Protocol ,中文是簡單物件存取協定。一種基於 XML 的交換資料協議規範。
目前已經很少人在使用,大多人都是使用 HTTP API,也就是我們上方所提到且實測的。
## curl 指令
curl 指令操作簡單、在 terminal 就可以發送 request (需下載)。除了支援 HTTP request 之外,還可以上傳跟下載檔案。以下會簡單介紹幾種常用的 curl 指令,更多可以看[ TechBridge 的介紹文章](https://blog.techbridge.cc/2019/02/01/linux-curl-command-tutorial/)及另一篇[文章](http://blog.kent-chiu.com/2013/08/14/testing-rest-with-curl-command.html),寫得非常淺顯易懂。
### 基本格式
`curl [options] [URL..]`
### GET
`curl [URL]`
* 發一個 GET 的 Request 到這個網址,執行後會收到 Response。
* 可以組合其他指令,像是使用 `curl [URL] > index.html`。就下載此 response 到 index.html 裡。
### 取得 response 的 header
1. `curl -I [URL]`
2. `curl -- head [URL]`
這邊有一篇[文章](https://www.eebreakdown.com/2016/10/curl-http.html)非常簡單的說明了如何使用 curl 做 http 的測試。
## 其他常用的 Command line 指令
### Ping
`ping [Url]`
測試後方放入的網址是否可順利連結上。
### telnet
`telnet [URL] [Port]`
查詢是否可以連接到指定的 port。
剛開始無法使用,參考了[這篇文章](https://www.namecheap.com/support/knowledgebase/article.aspx/9667/2194/what-are-traceroute-ping-telnet-and-nslookup-commands#telnet) ,解決了第一步無法使用。
經由 telnet 連到 IP 位址的 port 後,可以輸入「get/」就會取得 GET request 的資料。其它指令也是可以直接操作。
補充現狀:剛先透過 `nslookup` 查詢 google.com 的 IP 位址,再透過 `telnet` 查詢 port。但目前還是似乎無法使用 `telnet` 的指令,可使用的指令是 `telnet ptt.cc`。
## 實際串接 TWITCH API 所遇到的問題
基本上按照串接 TWITCH API 的[教學文件](https://dev.twitch.tv/docs/api/)即可,但我還是遇到非常多的問題。這邊紀錄幾個非常耗費我耐心與腦力的問題,避免之後再犯:
![](https://i.imgur.com/TQSIv1n.png)
1. STEP 1 :註冊完 Twitch 帳戶後在這邊註冊應用程式,重新導向網址後還需要加上 port。
2. STEP 2 :在 terminal 輸入文件上的 sample code 時,要注意的地方有很多。
* `curl: (6) Could not resolve host:` 和 `curl: (1) Protocol "'https" not supported or disabled in libcurl`的問題解法:裡面的單引號('')全數都要換成雙引號("")。
* 文件內 sample code 的斜槓是讓你換行,但 cmder 無法同時執行兩行,需要手動把 / 刪除。
* Client-ID冒號後不可以有空格。
參考資料:[單引號換雙引號](https://stackoverflow.com/questions/6884669/curl-1-protocol-https-not-supported-or-disabled-in-libcurl)
## 實做 API
可參考保哥的[影片](https://www.youtube.com/watch?v=uFKa4xrc42c)。
###### tags: `HTTP Request`、`API`