超完整 Express Imgur 套件上傳教學

前言

Imgur 是一個非常好用的網路相簿服務,主要有提供免費的圖片儲存服務,開發上也可以拿來當作上傳練習,甚至是 Blog 文章的圖片儲存庫,所以這一篇就來分享一下在 Express 的 Imgur 的圖片上傳教學。

Imgur 事前準備

Imgur Album 建立

一開始先來學一下如何建立 Album,因此等一下後面上傳圖片都會指定到特定的 Album 中統一管理。

其實 Imgur 早期是可以直接建立一個 Album,但是後來不知道為什麼隱藏了 Album,按鈕並且非常難建立 Album,所以這一個流程基本上有八成以上的人找不到,所以會建議你務必依據以下流程來操作。

首先請你先登入 Imgur 網站,登入成功後點一下使用者列表中的「images」選項

images

接下來找到「All images」的下拉選單,裡面會有一個「New Album」點它

New Album

會跳出一個關於 Album 相關的設定視窗,你就依照欄位填寫完畢之後按下 Save

Album

新增成功之後你就會看到一片空白,因為當前顯示的 Album 是你剛剛新增的 Album,而我們並沒有新增任何圖片進去,自然就會是空的無誤

Album

恭喜你這樣子就成功建立了一個 Album。

Imgur 的使用者體驗真棒

Imgur Album ID 取得

由於我們稍後會需要將圖片上傳到特定 Album,所以會需要 Album 的 ID,因此請先點一下使用者列表的「gallery profile」

gallery profile

接下來在右側找到「Albums」

Albums

接下來就是點一下「Posts」=> 「All」,不意外第一個就是你剛剛建立的 Album

Album

進入到 Album 之後你可以看一下它的網址,我們只需要下方圖片紅框圈起來部分就好,那部分就是我們要找的 Album ID,這邊就請先記憶著,稍後 Express 時會使用到

Album ID

註冊 Imgur 應用程式

接下來我們要來註冊一個 Imgur 應用程式,因為我們會需要 client_idclient_secret 來上傳圖片,你可以點一下下方連結進入註冊

註冊 Imgur 應用程式

進入之後你會看到這個畫面

註冊

需要填寫的欄位如下

  • Application name
    • 任意名字
  • Authorization type
    • 選 OAuth 2 authorization without a callback URL
  • Email
    • 聯絡你用

ps.如果你「Authorization type」是選「Anonymous usage without user authorization」的話,那「Authorization callback URL」就要填入「https://imgur.com

申請應用程式

申請之後你會看到這個畫面,請記好你的 client_idclient_secret,尤其是 client_secret 不可以搞丟,如果搞丟就只能重新生成而已

申請成功

那麼這樣就申請完畢了,如果真的不小心遺失 client_secret 的話,可以點這個 連結 到「Applications」中點一下「generate new secret」重新生成

重新生成 client_secret

Imgur Refresh Token 取得

前面我們已經準備了 client_idclient_secret,但實際上還需要最後一樣鑰匙也就是 Refresh Token,而會需要 Refresh Token 是因為 Imgur 提供的 Token 是有時間限制的,那為了讓它可以自動刷新 Token,所以就必需要 Refresh Token 才可以。

取得 Refresh Token 的方式很特別,你需要將以下連結中的 「${Client ID}」換成我們剛剛申請的 Client ID

1
https://api.imgur.com/oauth2/authorize?client_id=${Client ID}&response_type=token

然後貼到瀏覽器網址列上按下 Enter 送出

網址列

這時候你會進入到一個警告畫面,只要確定這是你要用的應用程式就好,若沒問題就按下允許

允許

允許之後你會被跳回 Imgur 的畫面,然後你把當前畫面的 Url 複製下來,基本上會這麼長

1
https://imgur.com/#access_token=xxxxx&expires_in=xxxxx&token_type=bearer&refresh_token=xxxxx&account_username=xxxx&account_id=xxxx

但這邊注意看,我們只需要 Refresh Token 就好,把它記錄下來,稍後也會使用到

Refresh Token

Imgur 最後確認

最後這邊確定下流程,如果你有依照文章流程下來的話,你應該完成了以下動作

  • 建立一個空的 Album
  • 取得 Album ID
  • 取得 Client ID
  • 取得 Client Secret
  • 取得 Refresh Token

上述這幾樣基本上缺一不可,如果有缺少的話,可以再往前看一下 Imgur 流程。

Express Imgur

本身 Imgur 官方是有提供 API 可以給我們使用的,但是其實實際開發上如果有現成套件的話,基本上就會選擇用套件較快,而這邊我們會使用的就是「Imgur」這個同名套件,這邊我會區分成兩個版本提供範例程式碼。

Imgur 套件基本上有兩個版本,分別是 1.x 跟 2.x 的寫法,但大多網路上都是 1.x。

前端範例程式碼

而這邊前端範例程式都是如下參考,HTML 部分就不額外提供了。

1
2
3
4
5
6
7
8
9
10
11
const formData = new FormData();
formData.append('file-to-upload', e.target.form[0].files[0]);
axios.post('/api/v1/upload', formData, {
headers: {
'Content-Type': 'multipart/form-data',
},
})
.then((data) => {
console.log(data)
})
.catch(error => console.log(error));

一率我們都是採用 formData 格式傳送給後端。

如果你想要用 Postman 測試的話,只需要如下圖設置就好

Postman

除此之外這邊也會使用到 multer 來處理圖片,而這邊我就不多做說明了,直接貼上程式碼給予參考

1
npm install --save multer
1
2
3
4
5
6
7
8
9
10
11
12
const upload = multer({
limits: {
fileSize: 2 * 1024 * 1024,
},
fileFilter(req, file, cb) {
const ext = path.extname(file.originalname).toLowerCase();
if (ext !== '.jpg' && ext !== '.png' && ext !== '.jpeg') {
cb('檔案格式錯誤,僅限上傳 jpg、jpeg 與 png 格式。');
}
cb(null, true);
},
}).any();

Imgur 1.0.2

早期大多都是使用 1.0.2 的方式開發,因此如果你有特殊需求只能安裝舊版的話,你可以輸入以下 npm 指令

1
npm install --save imgur@1.0.2

而後端的部分程式碼如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
const imgur = require('imgur');

router.post('/', function(req, res, next) {
upload(req, res, () => {
imgur.setCredentials(process.env.IMGUR_EMAIL, process.env.IMGUR_PASSWORD, process.env.IMGUR_CLIENTID);
imgur
.uploadBase64(req.files[0].buffer.toString('base64'), process.env.IMGUR_ALBUM_ID)
.then((json) => {
res.send({ url: json.link });
})
.catch((err) => {
res.send(err.message);
});
})
});

Imgur 1.0.2 的版本基本上採用的認證方式是帳號密碼,而其他部分就是我們剛剛申請的 Client ID 與 Album ID。

我們可以看到 Imgur 1.0.2 並沒有使用到 Client Secret 跟 Refresh Token,而是採用傳統的密碼登入,那本身這是比較差的方式,但有時候確實是有可能需要使用舊版的。

Imgur 2.2.0

接下來做法就比較新一點,因此這邊建議要重新安裝 npm。

1
npm install --save imgur@2.2.0

由於我這邊要示範,因此直接指定版本。

這邊要注意一件事情除了安裝 imgur 套件之外,你也必須額外安裝 tslib 套件,否則你會出現 Error: Cannot find module 'tslib' 的錯誤訊息

1
npm install --save tslib

安裝完畢之後,你就可以將程式碼改成新版方式,新版方式就會使用到剛剛申請的所有東西囉

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
const { ImgurClient } = require('imgur');

router.post('/', function(req, res, next) {
upload(req, res, async () => {
const client = new ImgurClient({
clientId: process.env.IMGUR_CLIENTID,
clientSecret: process.env.IMGUR_CLIENT_SECRET,
refreshToken: process.env.IMGUR_REFRESH_TOKEN,
});
const response = await client.upload({
image: req.files[0].buffer.toString('base64'),
type: 'base64',
album: process.env.IMGUR_ALBUM_ID
});
res.send({ url: response.data.link });
})
});

那麼這樣子就可以將圖片上傳到 Imgur 囉

上傳成功後你也可以到你剛剛建立的 Album 看到圖片囉

上傳成功

注意事項

如果過程中你遇到「Imgur is temporarily over capacity. Please try again later.」是正常的,這時候你過段時間再戳一下應該就可以囉。

除此之外如果短時間請求太多次的話 Imgur 會暫時 429 停止你一下唷~

然後上方有使用到環境變數的部分,因此要自己轉換一下哩

1
2
3
4
IMGUR_CLIENTID=
IMGUR_CLIENT_SECRET=
IMGUR_REFRESH_TOKEN=
IMGUR_ALBUM_ID=

Liker 讚賞

這篇文章如果對你有幫助,你可以花 30 秒登入 LikeCoin 並點擊下方拍手按鈕(最多五下)免費支持與牡蠣鼓勵我。
或者你可以也可以請我「喝一杯咖啡(Donate)」。

Buy Me A Coffee Buy Me A Coffee

Google AD

撰寫一篇文章其實真的很花時間,如果你願意「關閉 Adblock (廣告阻擋器)」來支持我的話,我會非常感謝你 ヽ(・∀・)ノ