訂閱網址是入口,Base64 是編碼,分享連結描述單一伺服器,原生 JSON 則可能包含完整的執行設定。本文適合遇到「更新成功卻沒有伺服器」、「JSON 無法匯入」或需要移轉用戶端的使用者:先辨識回應內容,再選擇匯入入口,最後確認哪些欄位可以轉換、哪些設定必須另外保留。
一、先分清訂閱網址、回應內容與節點協定
一般所說的訂閱連結,是透過 HTTPS 取得內容的網址。用戶端向該網址提出請求,取得伺服器清單或設定文字後,再嘗試解析。網址中可能包含存取權杖;它本身不是 VMess 或 VLESS 協定,也不能只憑網址副檔名判斷回傳格式。同一個入口也可能依請求參數或用戶端識別資訊回傳不同內容。
常見清單的基本單位是分享連結,例如以 vmess:// 或 vless:// 開頭的文字。多筆連結逐行排列後,可以直接回傳,也可以整份進行 Base64 編碼。另一種回應則是 JSON,但「能用 JSON 解析器開啟」只代表語法正確,不代表用戶端知道該將它視為伺服器清單,還是完整設定。
| 格式 | 辨識線索 | 通常包含內容 | 應使用的入口 |
|---|---|---|---|
| 明文分享清單 | 每一行都以協定前綴開頭 | 多部伺服器的連線參數 | 分享連結或剪貼簿匯入 |
| Base64 清單 | 解碼後會得到多行分享連結 | 內容與明文清單相同 | 使用支援此格式的訂閱更新功能 |
| 原生設定 JSON | 常見頂層鍵為 inbounds、outbounds | 入站、出站、DNS、路由等設定 | 自訂設定或設定檔匯入 |
二、Base64 只改變表示方式,不會改變協定能力
Base64 將位元組表示為方便傳遞的文字,並不提供保密性。中文備註需要先轉成 UTF-8 位元組,再進行 Base64 編碼;反向處理時,則先還原位元組,再以 UTF-8 解碼。直接對包含中文的字串呼叫瀏覽器的 btoa(),可能會發生錯誤或產生錯誤結果。
標準 Base64 常見字元包括 +、/,結尾可能有 =。URL 安全變體會用 -、_ 取代前兩者,也可能省略填充字元。部分用戶端會相容這些差異,但不能假設所有匯入工具都會自動修正空格、截斷內容或多餘引號。
- 外層解碼:解碼整份訂閱回應,結果通常是多行分享連結。
- 內層解碼:傳統 VMess 分享格式在
vmess://後還有一段 Base64,解碼後才會得到單一節點的 JSON。 - 停止條件:看到完整的 URI 清單或結構清楚的 JSON 後,先辨識內容,不要反覆點選解碼。
- 錯誤訊號:如果回應以 HTML 登入頁、錯誤訊息或驗證碼頁面開頭,應先排查訂閱存取問題,而不是繼續轉換。
結論:先解碼一層,再決定匯入方式
若解碼結果是多行分享連結,請使用連結清單入口;若是包含入站、出站和路由的物件,則應確認自訂設定入口。編碼層數不能證明協定相容性。
三、VMess 分享 JSON 與原生設定不是相同結構
傳統 VMess 分享連結通常採用「vmess:// 加上 Base64 編碼 JSON」的格式。以下是此分享物件的教學範例,並非可供連線的伺服器,也不能直接作為核心執行設定。網域使用保留的示例網域,連接埠 443 僅用於說明 TLS 情境。
{
"v": "2",
"ps": "格式示範",
"add": "example.invalid",
"port": "443",
"id": "123e4567-e89b-42d3-a456-426614174000",
"aid": "0",
"scy": "auto",
"net": "ws",
"type": "none",
"host": "example.invalid",
"path": "/edge",
"tls": "tls",
"sni": "example.invalid"
}
此處的 v 是分享格式標記,不是用戶端版本;ps 是備註;add、port 和 id 分別對應位址、連接埠和使用者識別資訊。net 描述傳輸方式;此範例中的 host 和 path 用於 WebSocket;sni 則對應 TLS 伺服器名稱。這些欄位各有用途,不能因為值相同就視為同一個欄位。
| 分享物件欄位 | 原生設定中的典型位置 | 轉換注意事項 |
|---|---|---|
add、port | outbounds[].settings.vnext[] 中的位址與連接埠 | 原生設定中的連接埠通常應為數字,不能只複製字串型別的值 |
id、scy | VMess 出站使用者項目中的 id、security | 欄位名稱不完全相同,需依照核心設定規範進行對應 |
net、path | streamSettings 及對應的傳輸設定 | 只有傳輸類型相符時,相應欄位才有意義 |
tls、sni | streamSettings.security 與 TLS 設定 | 協定加密參數與 TLS 設定屬於不同層級 |
原生 JSON 可能同時定義多個出站,並由路由規則選擇出口。匯出其中一個節點時,通常不會一併保存 DNS、分流規則、入站監聽位址或其他出站。因此,「原生 JSON 轉分享連結」往往只是擷取連線參數,而非完整設定的可逆壓縮。
四、本機互轉:先處理文字,再處理設定語意
「分享連結清單轉成 Base64」和「Base64 還原為清單」都只是編碼操作,可在本機完成。以下 JavaScript 只定義文字處理函式,不會送出網路請求。可以在自行建立的本機空白頁面開發者工具中執行;不要在陌生網站的主控台貼上真實訂閱內容,也不要執行來路不明的轉換指令碼。
function encodeUtf8Base64(text) {
const bytes = new TextEncoder().encode(text);
const binary = Array.from(bytes, byte =>
String.fromCharCode(byte)
).join("");
return btoa(binary);
}
function decodeUtf8Base64(input) {
let text = input.trim()
.replace(/\s+/g, "")
.replace(/-/g, "+")
.replace(/_/g, "/");
if (!/^[A-Za-z0-9+/]*={0,2}$/.test(text)) {
throw new Error("內容不是預期的 Base64 文字");
}
if (text.length % 4 === 1) {
throw new Error("長度異常,請確認複製內容是否完整");
}
text += "=".repeat((4 - text.length % 4) % 4);
const binary = atob(text);
const bytes = Uint8Array.from(binary, char =>
char.charCodeAt(0)
);
return new TextDecoder("utf-8", { fatal: true }).decode(bytes);
}
function packShareList(links) {
return encodeUtf8Base64(links.join("\n"));
}
function makeClassicVmessLink(shareObject) {
return "vmess://" + encodeUtf8Base64(JSON.stringify(shareObject));
}
// 僅驗證 UTF-8 往返,不使用真實訂閱憑證。
const sample = "中文備註\n第二行";
console.assert(
decodeUtf8Base64(encodeUtf8Base64(sample)) === sample
);
- 還原清單:對回應文字呼叫
decodeUtf8Base64(),確認輸出確實是逐行排列的分享連結。此函式不會自動判斷協定,也不會修復損毀的內容。 - 包裝清單:將每一筆完整 URI 放入陣列,再交給
packShareList()。換行符號是項目分隔符,不能將多筆 URI 無分隔地串接。 - 產生 VMess:只有輸入物件已符合傳統 VMess 分享欄位時,才使用
makeClassicVmessLink()。此函式不會自動將任意原生設定轉成正確的節點。 - 驗證結果:先在用戶端匯入為測試項目,逐項核對位址、連接埠、UUID、傳輸、TLS 和伺服器名稱,再測試連線。
真正的「原生設定轉分享連結」還需要語意轉換器:決定要匯出哪個出站、辨識協定與傳輸、對應欄位,再確認目標分享格式能否表達所有參數。若有欄位無法表示,應停止轉換或記錄缺漏項目,不能默默捨棄後宣稱轉換成功。
五、如何選擇三款用戶端的匯入入口
先依用途選擇:需要持續更新的一組伺服器,使用訂閱;臨時移轉單一節點,使用分享連結;需要完整控制 DNS、路由與出站的設定,再考慮原生 JSON。用戶端介面負責匯入與管理,核心負責執行協定,兩者的相容範圍都應分別確認。
訂閱入口
建議儲存訂閱網址,由用戶端定期或手動取得伺服器清單。更新方便,但伺服器端回傳的格式必須能由目前的匯入工具辨識。
適用情境:需要持續管理且經常變動的伺服器清單。
分享連結入口
從剪貼簿匯入一筆或多筆 URI,方便核對參數。通常不會自動保留與原訂閱的更新關係。
適用情境:臨時測試、單一節點移轉及格式疑難排解。
自訂設定入口
透過用戶端提供的自訂設定功能載入原生 JSON。設定必須符合實際使用的核心,路由及 DNS 的接管方式也應另外確認。
適用情境:已有完整設定,且需要保留進階出站與路由的使用者。
v2rayN 用於桌面端;v2rayNG 是使用 Xray 核心的 Android 用戶端;v2flyNG 則是使用 v2fly 核心的 Android 用戶端。VMess 分享連結是常見的交換方式,但實際支援的傳輸及擴充參數仍依版本而異。尤其是針對 Xray 的擴充設定,不能假設 v2fly 核心能直接執行。
-
保留原有設定
先保留目前可用的項目與原始回應。排解問題時請使用獨立的訂閱群組,不要一開始就清空所有伺服器。
-
桌面端新增訂閱
v2rayN 常見操作路徑為「訂閱分組」→「訂閱分組設定」→「添加」:填寫備註與網址並儲存,再從「訂閱分組」選單執行更新。跨平台介面和不同版本的按鈕文字可能略有差異。
-
Android 新增訂閱
v2rayNG 常見操作路徑為右上角選單「⋮」→「訂閱分組設定」→「+」;儲存後回到主畫面,從「⋮」→「更新訂閱」取得項目。請勿將訂閱網址當成伺服器位址填入。
-
以單一項目交叉比對
在 v2rayN 的「伺服器」選單中選擇從剪貼簿匯入;v2rayNG 常見入口為主畫面「+」→「從剪貼簿匯入」。使用同一筆分享連結測試,可分辨是訂閱取得失敗,還是節點解析失敗。
-
確認核心
在 v2flyNG 中使用訂閱設定或剪貼簿匯入入口,並確認 v2fly 是否支援相關參數。原生 JSON 應使用該版本提供的自訂設定入口,不要直接貼到訂閱網址欄位。
六、匯入失敗時,依取得、解析、執行分層排查
更新提示完成,只能表示某個更新流程已經結束,不足以證明所有項目都成功解析。反過來說,項目已出現在清單中,也不代表傳輸與 TLS 參數完全正確。保留錯誤發生的階段,比反覆修改編碼更有效。
| 狀況 | 優先檢查項目 | 下一步 |
|---|---|---|
| 訂閱請求失敗 | 網址是否完整、權杖是否失效,以及是否回傳 401 或 403 | 確認服務提供者的授權狀態,不要試圖透過轉碼繞過權限限制 |
| 回傳 200,但沒有項目 | 回應是否為登入頁、錯誤 JSON 或不相容格式 | 辨識本文類型,再改用正確的匯入入口 |
| Base64 解碼錯誤 | 文字是否遭到截斷、是否混入引號,以及是否支援該變體 | 重新複製原文,檢查長度及實際回應內容 |
| JSON 可解析,卻無法匯入 | 是否混淆了分享物件、設定檔或介面錯誤物件 | 檢查頂層鍵與用戶端預期的結構 |
| 項目存在,但連線失敗 | 連接埠、UUID、傳輸、TLS、SNI 和路徑 | 依照原始設定逐項比對,再檢查網路是否可連線 |
將原生 JSON 整份轉成 Base64,就能變成通用訂閱嗎?
不能。編碼不會改變資料結構。解碼後仍是原生設定;如果用戶端只接受分享連結清單,仍然無法依清單解析。請使用支援該設定的入口,或有選擇地擷取可表達的節點參數。
匯入分享連結後,為什麼原本的分流規則不見了?
分享連結通常只描述單一節點,不包含完整的路由架構。用戶端既有的分流設定,與原生設定中的規則也可能屬於不同的管理層級。移轉前應分別保存 DNS、路由、入站及其他出站設定。
訂閱更新後,手動修改的參數為什麼還原了?
訂閱項目通常以遠端內容為準,更新時可能會重建或覆寫本機項目。需要長期保留的修改,應另外儲存為獨立設定,並確認它不會隨原訂閱自動變更。
結論:先確保欄位完整,再考慮轉換便利性
優先使用服務提供者明確支援的訂閱格式。必須移轉時,先用一個節點驗證轉換結果,並另外保存路由與 DNS;確認可用後再批次處理。