Base64 是編碼方式,訂閱是取得節點集合的方法,原生 JSON 則是核心執行設定,三者並非同一層級。本文適合遇到「訂閱能開啟卻無法匯入」、「解碼後仍是一串字元」或「分享連結不能當成設定檔使用」的讀者。依序檢查外層訂閱、單筆連結與核心欄位,就能判斷該解碼、匯入還是補齊設定。
先釐清三種格式:訂閱網址不是節點設定
結論:先確認取得的內容,再選擇匯入方式。以 https:// 開頭的訂閱網址只是取得內容的入口;回應本文才會決定用戶端收到的是 Base64 節點清單、明文分享連結,還是其他格式。直接對網址本身進行 Base64 解碼,不會得到伺服器設定。
訂閱網址與節點清單
推薦常見的回應內容是多筆分享連結逐行排列,再將整份內容進行 Base64 編碼。用戶端會儲存訂閱網址,更新時重新取得節點;這種方式適合持續維護節點清單,但並非所有服務都採用相同格式。
適用情境:服務提供有效的訂閱網址,且需要持續更新節點。
vmess:// 分享連結
本文討論常見的 v2 分享格式:前綴後方是以 Base64 編碼的節點 JSON。內容主要描述單一 VMess 出站所需資訊,不包含完整的本機監聽、DNS 與路由策略。
適用情境:移轉單一節點、從剪貼簿匯入,以及透過 QR Code 傳送。
核心原生 JSON
通常包含 inbounds、outbounds,也可設定 dns 與 routing。結構與支援欄位依核心及版本而異,不能只看副檔名判斷是否相容。
適用情境:自訂入站、路由規則,以及指定核心的設定管理。
Base64 不具保密功能。訂閱網址中的存取權杖、節點 UUID 和分享 QR Code 都可能讓他人取得連線權限。排查問題時請使用本機編輯器,不要將真實內容貼到線上解碼網站;提供記錄檔給他人前,也應移除這些識別資訊。
Base64 訂閱解碼:分別處理外層清單與內層節點
常見的兩層結構如下:先解碼外層 Base64,取得多筆 vmess:// 連結;再選取其中一筆,移除前綴並再次解碼,才會得到節點 JSON。不能對所有輸入一律解碼兩次。若訂閱本文已直接以分享連結開頭,外層就不需要解碼。
-
取得回應本文
使用本機工具檢視訂閱回傳的內容。如果看到登入頁面、驗證碼或錯誤頁面,請先處理存取問題;HTML 頁面不是節點清單,即使請求成功也不代表訂閱可用。
-
辨識外層格式
如果本文直接出現
vmess://或vless://,請逐行讀取。若內容是連續的編碼字串,可嘗試進行 Base64 解碼;若以{或[開頭,請先按 JSON 格式檢查。 -
分離節點列
將解碼結果依換行拆分,移除每行前後空白並篩除空行。不要把多筆連結合併成一筆,也不要更動連結內的字元。
-
解析單筆連結
針對本文所述的 VMess v2 格式,移除
vmess://前綴後進行解碼,再解析 JSON。若內容不是這種結構,請確認分享格式的來源,不要硬套欄位。
以下函式可在本機瀏覽器主控台使用,支援標準 Base64 與常見的 URL 安全字元,會補上省略的尾端填充,並以 UTF-8 還原中文備註。執行前請先閱讀程式碼。函式不會傳送網路請求,也不會自動讀取剪貼簿。
function decodeBase64Utf8(input) {
let value = input.trim().replace(/\s+/g, "");
value = value.replace(/-/g, "+").replace(/_/g, "/");
if (!/^[A-Za-z0-9+/]*={0,2}$/.test(value)) {
throw new Error("輸入包含非 Base64 字元");
}
value = value.replace(/=+$/, "");
if (value.length % 4 === 1) {
throw new Error("Base64 長度不完整");
}
value += "=".repeat((4 - value.length % 4) % 4);
const binary = atob(value);
const bytes = Uint8Array.from(binary, char => char.charCodeAt(0));
return new TextDecoder("utf-8", { fatal: true }).decode(bytes);
}
function readSubscription(body) {
const text = body.trim();
const decoded = /^(vmess|vless):\/\//i.test(text)
? text
: decodeBase64Utf8(text);
return decoded.split(/\r?\n/)
.map(line => line.trim())
.filter(Boolean);
}
function readVmess(link) {
const value = link.trim();
if (!value.startsWith("vmess://")) {
throw new Error("需要 vmess:// 連結");
}
return JSON.parse(decodeBase64Utf8(value.slice(8)));
}
readSubscription 僅示範「明文連結清單或其 Base64 編碼」這一種訂閱格式,並非通用訂閱解析器。遇到其他結構時請停止操作,並查看服務提供者的格式說明。Base64 解碼成功只表示內容可讀,不代表節點有效或帳號仍有使用權限。
解析 vmess://:分享欄位如何對應原生設定
以下是用於說明結構的 VMess v2 節點物件。example.com 是文件專用的示例網域,UUID 也僅供示範,無法用來連線至代理伺服器。欄位 v 的值 "2" 代表分享格式版本,不是用戶端或核心版本。
{
"v": "2",
"ps": "文件範例",
"add": "example.com",
"port": "443",
"id": "00000000-0000-4000-8000-000000000001",
"aid": "0",
"scy": "auto",
"net": "ws",
"type": "none",
"host": "example.com",
"path": "/ws",
"tls": "tls",
"sni": "example.com"
}
| 分享欄位 | 原生出站位置 | 轉換注意事項 |
|---|---|---|
add、port | settings.vnext[].address、port | 位址是字串;原生設定中的連接埠則使用數字。 |
id、aid | settings.vnext[].users[].id、alterId | 本例的 aid 為 0,對應現代 VMess AEAD 用法。 |
scy | settings.vnext[].users[].security | 這是 VMess 使用者加密設定,不是 TLS 開關。 |
net | streamSettings.network | 本例使用 ws;不同傳輸方式不能只修改單一欄位。 |
host、path | wsSettings.headers.Host、wsSettings.path | 此處按 WebSocket 解讀,路徑中的查詢參數也必須保留。 |
tls、sni | streamSettings.security、tlsSettings.serverName | TLS 伺服器名稱與 WebSocket Host 屬於不同層級。 |
ps、v | 備註與分享格式資訊 | 這不是核心連線所需欄位,不應原封不動地放入出站設定。 |
轉換判斷:先保留傳輸語意,再調整欄位型別
逐項核對位址、連接埠、UUID、傳輸方式、TLS、SNI、Host 與路徑。不要把分享欄位 type: "none" 當成關閉 TLS 的依據,也不要用位址欄位自動覆蓋服務提供者明確指定的 SNI。
VMess 與 VLESS 是不同的通訊協定。vless:// 常見格式是包含使用者資訊、主機、連接埠與查詢參數的 URI,不能照搬「移除前綴後將 Base64 解碼成 JSON」的流程。將連結前綴從 VMess 改成 VLESS,也不會完成協定轉換;伺服器必須支援相應協定與身分設定。
轉成原生 JSON:除了節點,也要補齊入站設定
原生設定並不是將解碼後的節點 JSON 換個檔名。以下提供 Xray 常見的 VMess、WebSocket、TLS 完整範例:本機提供 SOCKS 入站,出站使用上方的示範節點。實際欄位仍須依照安裝的核心版本確認;這不代表所有 V2Fly 版本都接受相同設定。
{
"log": {
"loglevel": "warning"
},
"inbounds": [
{
"tag": "local-socks",
"listen": "127.0.0.1",
"port": 10808,
"protocol": "socks",
"settings": {
"auth": "noauth",
"udp": true
}
}
],
"outbounds": [
{
"tag": "proxy",
"protocol": "vmess",
"settings": {
"vnext": [
{
"address": "example.com",
"port": 443,
"users": [
{
"id": "00000000-0000-4000-8000-000000000001",
"alterId": 0,
"security": "auto"
}
]
}
]
},
"streamSettings": {
"network": "ws",
"security": "tls",
"tlsSettings": {
"serverName": "example.com",
"allowInsecure": false
},
"wsSettings": {
"path": "/ws",
"headers": {
"Host": "example.com"
}
}
}
}
]
}
此範例未加入分流規則,預設會將流量交由第一個出站處理。它也不會自動設定系統代理;應用程式必須明確使用 127.0.0.1:10808 的 SOCKS 服務。127.0.0.1 會將監聽範圍限制在本機,排查問題時不應直接改成對所有網路介面開放的位址。
- 先檢查連接埠。若現有用戶端已占用 10808,第二個核心可能無法啟動。可以停止重複執行的執行個體,或同步修改本機入站與應用程式的代理連接埠。
- 維持憑證驗證。範例保留
allowInsecure: false。遇到憑證錯誤時,請檢查系統時間、伺服器名稱與憑證鏈,不要直接關閉驗證。 - 區分設定的適用範圍。透過用戶端匯入自訂設定時,系統代理、TUN 與內建路由是否繼續生效,取決於匯入模式;不要假設它與一般節點模式相同。
反向轉換:分享連結只能帶走部分設定
若要從單一 VMess 出站產生分享連結,需先從原生設定擷取伺服器、使用者與傳輸欄位,組成前述的 v2 分享物件,再以 UTF-8 編碼成 Base64,最後加上 vmess:// 前綴。不能直接將整份原生設定編碼後加上此前綴,因為產生的格式不符合常見的節點匯入慣例。
function encodeBase64Utf8(text) {
const bytes = new TextEncoder().encode(text);
let binary = "";
for (const byte of bytes) {
binary += String.fromCharCode(byte);
}
return btoa(binary);
}
function createVmessLink(share) {
return "vmess://" + encodeBase64Utf8(JSON.stringify(share));
}
function createBase64Subscription(links) {
return encodeBase64Utf8(links.join("\n"));
}
createVmessLink 接收的是依照欄位表整理好的分享物件,不會自動擷取複雜設定,也不會驗證節點參數。createBase64Subscription 接收分享連結陣列,並產生常見格式的訂閱本文;它不會建立可更新的訂閱網址,後者仍須由受控服務提供回應。
- 原生設定若有多台伺服器或多位使用者,必須明確選定要使用的組合。不要預設陣列中的所有內容都屬於同一筆連結。
- 單一 VMess 分享連結通常無法完整保留本機入站、DNS、路由、記錄層級與多出站策略。
- 若進階傳輸欄位沒有對應的分享格式規範,匯入時可能會遺失。若要完整移轉,請使用設定備份,並確認目標核心相容。
移轉判斷:節點用連結,策略用備份
只需移轉伺服器連線資訊時,使用分享連結;需要保留路由、DNS 與本機監聽設定時,使用經過檢查的設定備份。轉換後逐項核對重要欄位,不要以「匯入成功」作為完整無損移轉的證明。
用戶端匯入:分開使用訂閱、剪貼簿與自訂設定
用戶端能辨識某種外層格式,不代表其核心支援其中所有協定與傳輸方式。v2rayN 是桌面用戶端;v2rayNG 使用 Xray 核心;v2flyNG 使用 V2Fly 核心。請先確認連線參數與核心功能相符,再選擇匯入方式。以下選單以常見的中文介面為參考,不同發行版本的名稱與位置可能有所不同。
| 輸入內容 | v2rayN | Android 用戶端 |
|---|---|---|
| 訂閱網址 | 前往「訂閱分組」→「訂閱分組設定」,新增網址後更新分組。 | 在 v2rayNG 側邊欄的「訂閱分組設定」新增網址,再從主畫面選單點選「更新訂閱」。v2flyNG 請依目前版本的訂閱入口操作。 |
| 單筆分享連結 | 複製完整連結,選擇「伺服器」→「從剪貼簿匯入批次 URL」。 | 在 v2rayNG 主畫面右上角點選「+」→「從剪貼簿匯入」。v2flyNG 請使用分享連結匯入功能。 |
| 原生 JSON 檔案 | 使用「伺服器」選單中的「新增自訂設定伺服器」,並確認所使用的核心。 | 使用目前版本的自訂設定匯入功能;不要將內容貼到訂閱網址欄位,跨核心移轉前請先檢查欄位。 |
v2rayN 常見的訂閱更新操作位於「訂閱分組」→「更新目前訂閱(不透過代理)」。此選項控制取得訂閱時是否經由代理,不會將節點的連線方式改成直連。若訂閱網站必須透過代理存取,請選擇相應的透過代理更新方式,並先確認目前的代理連線正常。
- 更新失敗先檢查回應內容。網址過期、存取權杖失效或回傳網頁時,不應繼續轉換節點格式。請先檢查更新記錄與訂閱權限。
- 匯入失敗先檢查結構。確認是否多複製了引號、缺少前綴,或誤將完整 JSON 當成分享連結。若中文備註出現亂碼,請檢查 UTF-8 編碼與解碼。
- 連線失敗再檢查參數。節點已出現在清單中卻無法連線時,請核對 UUID、連接埠、WebSocket 路徑、Host、TLS 與 SNI,不要反覆重新進行 Base64 編碼。
- 手動修改請另行儲存。更新訂閱可能會重建節點項目。臨時修改的節點適合複製到獨立分組,並記錄與訂閱原始值之間的差異。
常見問題:解碼成功,為什麼仍無法使用?
解碼後仍是 vmess://,代表解碼失敗嗎?
不是。外層訂閱包含分享連結清單,看到 vmess:// 通常表示已取得節點列。若要查看節點 JSON,請再解碼單筆連結前綴後方的內容;若只是要匯入用戶端,通常可直接使用完整分享連結。
任何 JSON 都能當作 V2Ray 原生設定嗎?
不行。VMess 分享物件、用戶端設定備份與核心設定都可能使用 JSON,但欄位意義各不相同。請先確認是否具備該核心要求的入站、出站結構,再檢查協定與傳輸欄位。JSON 語法正確,只代表文字格式可以解析。
將本機節點清單編碼後,就能建立可自動更新的訂閱嗎?
這只有訂閱本文,並沒有訂閱服務。自動更新還需要穩定且具備存取控制的取得網址。將本文存到本機,不會讓其他裝置自動收到變更;若只需傳送一次節點,分享連結更直接。
用戶端匯入成功,代表連線參數完整嗎?
不一定。解析器可能接受基本欄位,卻忽略不支援的擴充參數。匯入後請開啟節點編輯畫面,核對傳輸類型、路徑、Host 與 TLS 伺服器名稱,再實際測試連線。QR Code 也只是文字載體,不會補上缺少的參數。