使用又拍雲極速搭建圖床

粥里有勺糖發表於2024-04-13

前言

某天在群裡摸 🐟 ,聊到了圖床相關的話題,群友推薦了 又拍雲

說有活動,可以白嫖儲存,10G + 15G(HTTP/HTTPS 流量) 。筆者之前一直用的七牛雲 10G + 10G(回源流量)

又拍雲 七牛雲
註冊送1個月的代金券 + 網站掛推廣送1年代金券 註冊即可送每月都有

筆者就花了點時間研究了一下又拍雲的 SDK 和物件儲存,能力上完全可以平替七牛雲,於是就花了一點時間給圖床應用加上了又拍雲的支援。

效果

大家可以訪問 https://imgbed.sugarat.top/ 直接體驗,預設已配置 又拍雲 儲存

下面將介紹 又拍雲物件儲存配置,關鍵API用法,如何接入上述圖床。

物件儲存服務建立

這裡直接省略賬號註冊,參加推廣活動等步驟,直接進入物件儲存配置頁面。

訪問物件儲存控制檯,點選建立服務

這個"服務"和其它平臺的 Bucket(桶) 類似,可以理解為儲存空間的概念。

填一下服務名稱(全平臺唯一),繫結賬號即可

服務建立完,需要的東西基本都有了,是不是非常簡單!

  • 服務名:自定義
  • 賬號:自定義
  • 密碼:自動生成
  • 域名:測試域名 serviceName.test.upcdn.net

API 使用

token 生成

這裡推薦使用 token 認證 根據文件:認證鑑權可知生成方式如下:

看不懂?沒關係 GPT 可以幫你,直接複製丟給它。

這不程式碼就來了。

我們可以適當最佳化一下,不需要用到第三方庫base64-js,直接使用 Node.js 的內建模組crypto 即可。

import crypto from 'crypto'

/**
 * 生成 upyun 上傳token
 * @param {*} operator 賬號
 * @param {*} password 密碼
 * @param {*} method 方法(PUT)
 * @param {*} uriPrefix 請求公共字首
 * @param {*} date 過期時間
 * @returns 上傳憑證
 */
function generateUpyunToken(operator, password, method, uriPrefix, date) {
  // 密碼的md5值,秘鑰
  const secret = crypto.createHash('md5').update(password).digest('hex')

  // 構造用於計算校驗值的字串
  const value = `${method}&${uriPrefix}&${date}`

  // 使用 hmac-sha1 演算法生成token
  const token = crypto.createHmac('sha1', secret) // 使用密碼的MD5值作為秘鑰
    .update(value) // 設定用於計算校驗值的字串
    .digest() // 計算校驗值
    .toString('base64') // 轉換為base64 格式

  // 組合成要求的格式
  return `UPYUN ${operator}:${token}`
}

程式碼非常簡潔明瞭,使用方式如下

const token = generateUpyunToken('賬號',
  '密碼',
  'PUT',
  '服務名/資源公共字首路徑', // 服務名 + 公共資源字首路徑構成
  new Date().getTime() + 1000 * 60 * 60 * 24 * 90 // 計算過期時間 90天后的日期
)

理論上這個 token 也可以在前端生成,呼叫和後端一致的演算法即可。

前端上傳

① 安裝 upyun sdk

npm i upyun

② 上傳示例

根據文件,可以看到客戶端上傳需要的引數。

  • Authorization:前面透過生成的token
  • X-Date:請求日期時間,GMT 格式字串
  • X-Upyun-Uri-Prefix:服務名 + 資源公共字首路徑
  • X-Upyun-Expire:過期時間

下面就是核心的上傳方法。

import upyun from 'upyun'

const service = new upyun.Service('服務名')
const client = new upyun.Client(service, () => ({
  'Authorization': '前面透過生成的token',
  'X-Date': new Date().toUTCString(),
  'X-Upyun-Uri-Prefix': '服務名/資源公共字首路徑',
  'X-Upyun-Expire': date, // 前面生成 Token 時的 date 引數
}))

const sourceKey = '資源公共字首路徑/資源名' // 'test/imgs/abc.png'

// 呼叫上傳
client.putFile(sourceKey, file) // 返回值 Promise<boolean>

③ 方法封裝

我們可以簡單封裝一下,方便呼叫

interface UPYunConfig {
  /**
   * 服務名
   */
  serviceName: string
  /**
   * 上傳憑證
   */
  token: string
  /**
   * 資源公共字首
   */
  prefix: string
  /**
   * 過期時間 new Date().getTime() + 1000 * 60 * 60 * 24 * 90
   */
  date: number
  /**
   * 域名(用於拼接最後的訪問連結)
   */
  domain: string
  /**
   * 最後的資源名,建議使用 uuid 或者檔案的 MD5
   */
  filename?: string
}
async function uploadFile(file: File, ops: UPYunConfig) {
  const { serviceName, prefix, token, date, domain, filename } = ops

  const service = new upyun.Service(serviceName)
  const client = new upyun.Client(service, () => ({
    'Authorization': token,
    'X-Date': new Date().toUTCString(),
    'X-Upyun-Uri-Prefix': `${serviceName}/${prefix}`,
    'X-Upyun-Expire': date,
  }))

  const key = `${prefix}/${filename || file.name}`

  const isSuccess = await client.putFile(key, file)
  // 返回最後可以用於訪問的連結
  return isSuccess ? Promise.resolve(`${domain}/${key}`) : Promise.reject(new Error('上傳失敗'))
}

接入純靜態圖床

上述邏輯我都封裝在了自己的圖床應用中:GitHub: image-bed-qiniu

只需要在 cli 目錄下,修改 .env 配置檔案

# 又拍雲相關配置
UPYUN_OPERATOR=operator
UPYUN_PASSWORD=password
UPYUN_BUCKET=service-name
UPYUN_DOMAIN=http://service-name.test.upcdn.net
UPYUN_PREFIX=image
UPYUN_SCOPE=default
# token有效期,預設3個月,單位秒,你可以自行設定(60*60*24*30)
# UPYUN_EXPIRES=2592000

執行 node upyun-token.js 即可生成需要的 token。

將其貼上配置到 線上的圖床應用,或者自己部署的均可 image-bed-qiniu:client

其它

線上使用,推薦 繫結自定義域名 和 開啟HTTPS 支援。

這兩個直接在平臺里根據指引操作即可,步驟也很簡單。

最後

後續準備提供一個圖床的 Docker 映象,這樣部署起來也更加方便。

大家有其它可白嫖的圖床也可推薦推薦一下。

相關文章