開發者文件
整合動詞圖雲
本文說明如何在網頁、iOS 及 Android 應用程式中正確存取動詞圖雲的圖片網域, 包含必要的請求設定與使用注意事項。
使用規範
僅限 HTTP GET
圖片網域只開放 GET 請求,請勿使用 HEAD 或其他方法。
帶上 Referer(網頁)
在網頁中嵌入圖片時,確保瀏覽器帶上 Referer 標頭。
請勿頻繁重複請求
短時間大量請求相同圖片可能觸發 Cloudflare 防護機制。
App 環境(iOS / Android)發出的請求通常不含 Sec-Fetch-Dest 與 Referer,動詞圖雲會將其識別為合法的應用程式請求,無須額外設定即可正常存取。
網頁(HTML / JavaScript)
使用 <img> 標籤嵌入圖片
在 HTML 中嵌入圖片時,請加上 referrerpolicy 屬性,確保瀏覽器正確傳送 Referer 標頭,圖片才能順利顯示。
<img
src="https://i.verb.tw/aBcD1234.jpg"
referrerpolicy="no-referrer-when-downgrade"
alt="圖片描述"
/>使用 fetch() 下載圖片
const response = await fetch('https://i.verb.tw/aBcD1234.jpg');
const blob = await response.blob();
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = 'aBcD1234.jpg';
a.click();
URL.revokeObjectURL(url);在 Next.js / React 中使用
// 一般 <img> 標籤
<img
src="https://i.verb.tw/aBcD1234.jpg"
referrerPolicy="no-referrer-when-downgrade"
alt="圖片描述"
/>
// Next.js <Image> 元件(需設定 remotePatterns)
// next.config.js
images: {
remotePatterns: [
{ protocol: 'https', hostname: 'i.verb.tw' },
],
}iOS(Swift)
iOS 的 URLSession 預設不帶 Sec-Fetch-Dest,動詞圖雲會視為合法的 App 請求,可直接存取,無需額外設定。
URLSession 原生下載
let url = URL(string: "https://i.verb.tw/aBcD1234.jpg")!
var request = URLRequest(url: url)
request.httpMethod = "GET"
// 請使用 GET,勿使用 HEAD
let (data, _) = try await URLSession.shared.data(for: request)
let image = UIImage(data: data)使用 Kingfisher
import Kingfisher
let url = URL(string: "https://i.verb.tw/aBcD1234.jpg")
imageView.kf.setImage(with: url)使用 SDWebImage
import SDWebImage
let url = URL(string: "https://i.verb.tw/aBcD1234.jpg")
imageView.sd_setImage(with: url)使用 Nuke
import Nuke
import NukeUI
// SwiftUI(推薦)
LazyImage(url: URL(string: "https://i.verb.tw/aBcD1234.jpg"))
// UIKit
let url = URL(string: "https://i.verb.tw/aBcD1234.jpg")!
Nuke.loadImage(with: url, into: imageView)Kingfisher、SDWebImage 與 Nuke 皆內建磁碟與記憶體快取,能有效避免重複請求,強烈建議搭配使用。
Android(Kotlin)
Android 主流圖片載入函式庫預設使用 GET 請求,且不帶 Sec-Fetch-Dest,與動詞圖雲完全相容,可直接使用。
使用 Coil(推薦)
// build.gradle.kts
implementation("io.coil-kt:coil-compose:2.6.0")
// Jetpack Compose
AsyncImage(
model = "https://i.verb.tw/aBcD1234.jpg",
contentDescription = "圖片描述",
)使用 Glide
Glide.with(context)
.load("https://i.verb.tw/aBcD1234.jpg")
.into(imageView)使用 OkHttp 直接下載
val client = OkHttpClient()
val request = Request.Builder()
.url("https://i.verb.tw/aBcD1234.jpg")
.get() // 明確使用 GET,避免函式庫預設 HEAD
.build()
client.newCall(request).enqueue(object : Callback {
override fun onResponse(call: Call, response: Response) {
val bytes = response.body?.bytes()
val bitmap = BitmapFactory.decodeByteArray(bytes, 0, bytes!!.size)
}
override fun onFailure(call: Call, e: IOException) {
// 處理錯誤
}
})請確認你的 HTTP 客戶端不會自動發送 HEAD 預檢請求。部分舊版函式庫在下載前會先送 HEAD 確認檔案大小,這在動詞圖雲會受到限制。
常見問題
圖片回傳 403 或被重導向,該怎麼辦?
使用網頁 <img> 嵌入時,若缺少合法的 Referer 標頭,會被 Hotlink 保護攔截。 請在標籤加上 referrerpolicy="no-referrer-when-downgrade"。
HEAD 請求回傳錯誤?
圖片網域僅開放 GET 請求,HEAD 方法受到限制。若你的函式庫預設使用 HEAD 確認資源,請將請求方法改為 GET。
存取突然被封鎖?
短時間內對相同圖片發送大量請求可能觸發 Cloudflare 自動防護,導致 IP 暫時受阻。 建議在應用程式端實作本地快取(Kingfisher、Glide、Coil 皆有內建),避免重複請求同一資源。