https://lidemy-http-challenge.herokuapp.com/start
Lidemy HTTP Challenge

Lidemy HTTP Challenge(上) — Axios 通關攻略

JAS0N HUANG
9 min readJun 23, 2020

--

Lidemy HTTP Challenge,一個純文字 HTTP API 挑戰遊戲,非常技客的一個遊戲,通關通體舒暢!

防雷區

如同所有「遊戲攻略」,這裡也一定要防雷一下,非常強烈的建議:玩完遊戲,或者退一步,真的卡關卡到想哭的人再來看這篇心得,不然遊戲就不好玩了。或者我知道有些人就是要先被雷完才要看電影的那種,那你也可以先看完心得再去玩遊戲。

重點:趕快去玩遊戲

使用的工具

標題已經說明了,最主要的工具就是 Axios 這個套件,選擇它的原因是因為在胡立的程式導師實驗計畫裡有介紹一個串接 API 的 套件 request,但是連上它 npm 的頁面卻寫著大大的一行紅字:

This package has been deprecated

都這樣寫了,那就另外找別的套件來試試,在它的 Alternative libraries to request #3143 裡看到 Axios,覺得好像最近在不少地方看過這個名字,也不知道那些不少地方是什麼地方,反正這名字「阿修斯」也蠻帥的,就把它拿起來用囉!

另外,因為實力很弱,所以有一個地方還是開了瀏覽器,傳送資料時用了 querystrying 這個套件,連接 proxy 的地方用了 https-proxy-agent 這個套件。

所有使用到的工具:node 執行環境、瀏覽器、axios 、querystrying、https-proxy-agent。

const axios = require(‘axios’)
const qs = require(‘querystring’)
const httpsProxyAgent = require(‘https-proxy-agent’)

遊戲攻略

這裡只討論我自已使用 Axios 過關的方法,算是一個通關的記錄,寫出來的 code 可能對各位大神來說都很醜,還請各方大德不吝賜教。

詳細的設計理念以及遊戲裡藏的彩蛋可以直接去看胡立的文章:Lidemy HTTP Challenge 的設計以及彩蛋

第零關到第一關

簡單的開場介紹,用瀏覽器直接打開網址都可以解決,用 Axios 就只是傳送一個 GET request,直接把網址放進去就可以了。

const gameURL = 'https://lidemy-http-challenge.herokuapp.com'axios.get(
`${gameURL}lv1?token={GOGOGO}`
).then(res => {
console.log(res.data)
}).catch(err => {
console.log(err)
})

(之後的程式碼範例如果沒必要,就不會把 .then() 及 .catch()處理回傳資料與錯誤訊息的部分寫出來了。避免太多冗餘內容……)

把名字傳上去也只是單純的 query string,把上面網址的地方改成:

`${gameURL}lv1?token={GOGOGO}&name=XXXXX`

第二關

就是要傳 query string (id = XX)試一下 54 到 58 之間的數字,到這裡都還沒有真的用到串接 API 的功能,都只是傳送簡單的 HTTP GET request。

第三關

這一關對於還不知道 headers,不清楚 HTTP request 傳送內容的人來說可能就比較難了,因為這裡除了要開始串接圖書館 API ,還要改 headers 的資訊。

首先建立一個「設定檔」物件,在 headers 裡帶入 API 文件提到的 Content-Type

const config = { 
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
}
}

將網址以及要新增的資料存入變數:

const apiV1 = 'https://lidemy-http-challenge.herokuapp.com/api/'const requestBody = { 
name: "XXXXXXXXXXXX",
ISBN: 9XXXXXXXXXXXX
}

axio 傳送 POST request,這裡給的引數比較複雜,總共有三個部分

  1. 網址
  2. 要新增的資料,需經過 qureystring 套件處理過
  3. 設定檔,這裡只處理 headers 的內容
axios.post(
// 第一個
`${apiV1}books`,
// 第二個
qs.stringify(requestBody),
// 第三個
config
)

伺服器會回傳一個 response,一樣將 response 裡的 id 像第一關那樣用 query string 傳上去。

第四關

這一關的目標是要使用 API 裡提供的查詢功能依照提示的字串內容找到一本書,按照範例操作也不難。但是因為 node 沒辦法處理中文字串的傳送(可能需要設定編碼或是別的方法?知道怎麼處理的人可以跟我講一下),所以我就直接印出所有的書藉然後丟給 grep 去找了。

然後回去看到第三關的解法,喔!不是有 querystring 這個套件嗎?可以用在這裡吧?

先把 query string 丟給 querystring 處理,存到變數裡,然後丟進網址裡就可以把 grep 丟掉啦:

const requestString = qs.stringify({
q: "世界"
})
axios.get(`https://lidemy-http-challenge.herokuapp.com/api/books?${requestString}`)

第五關

前面的關卡都過了,這一關應該很簡單,把 request 換成 delete,依照 API 文件把要刪除的 id 加上就好。

第六關

可能因為基礎知識不夠,這一關確實難度增加不少,換了一個 API ,然後要先在網路上查 basic authorization 是什麼,然後還要看 Axios 的文件查怎麼在 Axios 裡使用,其實就是在API 網址後面多加一個 request 物件引數,放入登入資訊就好(格式如下),然後因為 Axios 會自已處理編碼問題,所以也不必特別去轉換成 base64 編碼。

const apiV2 = 'https://lidemy-http-challenge.herokuapp.com/api/v2/'axios.get(`${apiV2}me`,
{
auth: {
username: 'XXXXX',
password: 'XXXXXXXX'
}
})

第七關

處理完登入的問題,刪除就跟第五關一樣,EASY。

第八關

這一關比較麻煩一點,但是也不會太難,像第四關一樣把想查詢的”我”字用querystring 處理、存入變數然後再加進網址裡。

然後在接到 response 時處理回傳的資料,找到作者是四個字的書:

const meString = qs.stringify({
q: "我"
})

axios.get(`${apiV2}books?${meString}`,
{
auth: {
username: 'XXXXX',
password: 'XXXXXXXX'
}
})
.then(res => {
for (let i = 0;i < res.data.length; i++){
if(res.data[i].author.length === 4){
console.log(res.data[i])
}
}
})

接著把想要修改的新 ISBN 號碼同樣用 querystring 處理,傳入變數,再用 Axios 傳送一個PATCH request 就好了。

const ISBNString  = qs.stringify({
ISBN: "9981835423"
})
axios.patch(`${apiURLv2}books/72`, ISBNString,
{
auth: {
username: 'XXXXX',
password: 'XXXXXXXX'
}
})

第九關

這一關依照關卡指示在 headers 裡新增兩個內容就好,其實不會太難,但是因為之前沒有看過 User-Agent 這個東西,雖然看字面意思大概知道是幹什麼的,但是要填入什麼資料就完全沒概念了,單純搜尋 User-Agent 我覺得還不夠精準,應該要搜 User Agent Strings。

另外,因為 request 裡的自訂的內容越來越多,所以全部放到 config 這個物件裡,之後比較好新增內容或調用:

const config = {
auth: {
username: ‘admin’,
password: ‘admin123’
},
headers: {
‘Content-Type’: ‘application/x-www-form-urlencoded’,
‘User-Agent’: ‘XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX’,
‘X-Library-Number’: XX
}
}

然後傳送GET request 到指定網址,傳入 config 資訊,就可以拿到要求的 version 值。

axios.get(`${apiV2}sys_info`, config)

第十關

玩一下猜數字遊戲吧!

續集會有什麼精采的內容,讓我們下回分曉!

--

--