訂閱網址用來取得內容,Base64 負責文字編碼,分享連結描述單一節點,原生 JSON 則描述核心設定。本文適合遇到「訂閱清單空白」、「JSON 無法匯入」或需要移轉節點的使用者:先辨識回應格式,再於本機解碼,最後核對協定、傳輸方式與 TLS 欄位。轉換只會改變呈現方式,不會補上缺漏的伺服器參數,也不保證不同核心之間功能相同。
一、訂閱網址、分享連結與原生 JSON 有何不同
「V2Ray 訂閱」並不是一種固定的檔案副檔名。用戶端連線至 HTTPS 網址後,可能取得 Base64 文字、逐行分享連結、JSON,也可能是登入頁面。判斷格式時應查看實際回應本文,不能只看網址是否以 .txt 或 .json 結尾。
用戶端可辨識的訂閱網址
推薦由 v2rayN、v2rayNG 或 v2flyNG 擷取節點清單。前提是服務商提供的回應格式與目前用戶端相容;更新時仍可保留分組,不必每次手動複製節點。
適用情境:日常更新、在多部裝置上分別管理訂閱分組
逐行分享連結
每一行代表一個節點,常見前綴為 vmess://、vless://。適合排查單一節點;批次匯入後通常只是一次性的快照,不會自動保留原訂閱的更新關係。
適用情境:離線移轉、核對特定節點欄位
核心原生 JSON
可能同時包含入站、出站、DNS 與路由規則。這不是通用節點清單,通常須透過用戶端的自訂設定入口匯入,並符合所選核心的設定結構。
適用情境:保留明確的 DNS、路由與多出站設定
用戶端與核心也要分開看:v2rayN 是桌面用戶端;v2rayNG 使用 Xray 核心,v2flyNG 使用 V2Fly 核心。能匯入某種連結,只代表用戶端辨識了文字,不表示目前核心支援連結所宣告的所有功能。尤其涉及 REALITY 或特定流控時,應核對核心,而不是反覆進行 Base64 編解碼。
二、先辨識訂閱回應,再決定是否解碼
使用可信任的本機工具查看回應時,先移除開頭的空白,再觀察第一段內容。訂閱網址中的權杖通常可用來存取帳戶,請勿將完整網址、回應本文或 QR Code 傳給線上轉換網站。若瀏覽器顯示驗證碼、登入表單或錯誤頁面,應先排除存取問題。
| 看到的內容 | 可能的格式 | 下一步 |
|---|---|---|
vmess:// 或 vless:// | 明文分享連結清單 | 逐行匯入,不要再解碼整份本文 |
| 一長串英文字母、數字與少量符號 | 可能是 Base64 編碼清單 | 在本機解碼一次,再確認是否出現協定前綴 |
{ 或 [ | 可能是 JSON | 先解析結構,分辨 API 回應、節點物件與完整設定 |
<!DOCTYPE html> 或 <html | 網頁或存取遭封鎖的回應 | 檢查網址、登入狀態與訂閱效期 |
HTTP 狀態碼 200 只代表請求收到正常回應,不保證本文內容是節點。即使本文是有效的 JSON,也可能只包含錯誤碼與提示訊息。先判斷內容,再選擇匯入入口,比不斷切換代理或修改連接埠更有效。
三、如何將 Base64 訂閱還原為逐行分享連結
常見的傳統訂閱產生方式,是先以換行串接多個分享連結,再將整段 UTF-8 文字進行 Base64 編碼。解碼時反向操作即可。請留意標準 Base64 使用的 +、/,以及 URL 安全版本使用的 -、_,還有結尾可能省略的 = 填充字元。
以下是可供本機檢查的原生 JavaScript 函式。程式碼只處理傳入的字串,不會發出網路請求。可在自行建立的離線 HTML 頁面中執行;請勿將真實訂閱貼到不可信網頁的主控台。UTF-8 解碼相當重要,否則含中文的節點名稱可能會變成亂碼。
function base64ToText(source) {
const normalized = source
.replace(/\s+/g, "")
.replace(/-/g, "+")
.replace(/_/g, "/");
if (!/^[A-Za-z0-9+/]*={0,2}$/.test(normalized)) {
throw new Error("內容不符合 Base64 字元規則");
}
const body = normalized.replace(/=+$/, "");
if (body.length % 4 === 1) {
throw new Error("Base64 長度異常,請確認是否完整複製");
}
const padded = body + "=".repeat((4 - body.length % 4) % 4);
const bytes = Uint8Array.from(atob(padded), ch => ch.charCodeAt(0));
return new TextDecoder("utf-8", { fatal: true }).decode(bytes);
}
function textToBase64(text) {
const bytes = new TextEncoder().encode(text);
const binary = Array.from(bytes, byte => String.fromCharCode(byte)).join("");
return btoa(binary);
}
// 本機自我檢查,結果為 true。
console.log(base64ToText(textToBase64("訂閱格式測試")) === "訂閱格式測試");
- 將訂閱回應本文傳入
base64ToText,而不是 HTTPS 訂閱網址。 - 以換行拆分解碼結果,移除空行及行首、行尾空白;保留每個連結的完整字元。
- 檢查每一行的協定前綴,先選一個節點測試匯入,再批次處理。
- 若要重新產生傳統 Base64 清單,請使用
textToBase64(links.join("\n"))將逐行連結文字編碼;這不會自動產生可供存取的訂閱網址。
外層清單解碼一次後,vmess:// 後方仍可能是一段 Base64,這是單一節點本身的編碼結構,不代表解碼失敗。不要機械式地反覆解碼整份結果;應先依協定分別處理。
四、VMess 與 VLESS 分享連結如何對應 JSON 欄位
常見的 VMess 分享格式為 vmess:// 加上 Base64 編碼的節點 JSON,常見鍵名包括 add、port、id、net、host、path 與 tls。這是分享格式,不是可直接交由核心使用的完整設定;其中 v 代表分享格式版本,並非核心版本。
VLESS 分享連結通常會將使用者識別碼、位址與連接埠放在 URI 主體,並將傳輸參數放在查詢字串。以下使用保留示例網域與示範用 UUID,僅供說明欄位對應,不能用來實際連線。
vless://[email protected]:443?encryption=none&security=tls&type=tcp&sni=edge.example.com#TLS-demo
| 分享資訊 | 常見原生設定位置 | 檢查重點 |
|---|---|---|
| 位址與連接埠 | settings.vnext[].address / port | 遠端連接埠不是本機監聽連接埠 |
| 使用者 UUID | settings.vnext[].users[].id | 完整保留,不要將備註當成使用者識別碼 |
type=tcp | streamSettings.network | 使用目前核心支援的傳輸名稱 |
security=tls | streamSettings.security | 分別核對協定驗證資訊與傳輸類型 |
sni | tlsSettings.serverName | 符合伺服器憑證與設定要求 |
WebSocket 的 host / path | wsSettings.headers.Host / path | 不能直接用 SNI 取代 Host |
上述 VLESS 範例可對應為以下 Xray 出站片段。此片段不包含入站、DNS 與路由,因此不是完整可執行設定。複製到完整設定時,應放入適當的 outbounds 陣列位置,並依目前核心文件核對欄位。
{
"tag": "proxy",
"protocol": "vless",
"settings": {
"vnext": [
{
"address": "node.example.com",
"port": 443,
"users": [
{
"id": "00000000-0000-4000-8000-000000000001",
"encryption": "none"
}
]
}
]
},
"streamSettings": {
"network": "tcp",
"security": "tls",
"tlsSettings": {
"serverName": "edge.example.com",
"allowInsecure": false
}
}
}
encryption=none不代表停用 TLS:前者是 VLESS 使用者參數,後者則由傳輸安全層決定。- 不要自行加入
flow。流控值必須符合伺服器與傳輸方式的組合,並非所有 VLESS 節點都需要填寫。 - 產生 URI 查詢參數時,請逐一使用
encodeURIComponent;解析時可使用URL與URLSearchParams,避免再次解碼已解碼的值。 - IPv6 位址在 URI 中必須加上方括號;節點名稱中的空格、中文與
#也應依 URI 規則編碼。
五、為什麼原生 JSON 不一定能無損轉回訂閱
單一分享連結主要描述一個遠端連線。完整原生 JSON 還可能包含多個出站、規則比對、DNS 伺服器、流量嗅探及本機監聽設定。即使能從某個出站擷取出一條 VLESS 連結,也無法透過這條連結還原所有路由策略。因此,「JSON 轉訂閱」必須先說明是要擷取節點,還是保留整個執行環境。
轉換方案:分清節點移轉與完整設定移轉
只移轉節點
- 從
outbounds找出實際的代理出站,而非直連或封鎖出站。 - 擷取協定、位址、連接埠、驗證資訊、傳輸方式與 TLS 參數。
- 產生目前用戶端可辨識的分享連結,逐一測試匯入。
- 在目標用戶端另外設定 DNS、系統代理與分流規則。
保留完整設定
- 備份原始 JSON,記下對應的核心與實際版本。
- 檢查檔案路徑、監聽位址與連接埠是否被占用。
- 使用用戶端提供的自訂設定入口,不要當作一般訂閱匯入。
- 啟動後檢查記錄,並確認 DNS 與路由是否依預期運作。
結論:分享連結方便交換節點;原生 JSON 適合保留設定結構。重新編碼外層格式無法補足兩者之間的資訊落差。
同樣地,Xray 與 V2Fly 的 JSON 也不能只改副檔名就通用。特定協定擴充、傳輸欄位與 DNS 選項都可能不同。刪除不支援的欄位或許能讓設定通過解析,卻可能改變連線行為;應先確認伺服器要求,再決定是否移轉。
六、在 v2rayN 與 Android 用戶端中選擇正確的匯入入口
介面文字會隨版本變動,以下依常見中文選單說明操作目的;若裝置上的名稱不同,請尋找「訂閱分組」、「從剪貼簿匯入」或「自訂設定」等對應功能。不要將訂閱網址貼到只接受單一節點分享連結的編輯框,也不要把整份 JSON 填入伺服器位址欄。
- v2rayN 新增長期訂閱:前往「訂閱分組」→「訂閱分組設定」,新增分組並填入訂閱網址。儲存後,在訂閱選單選擇「更新訂閱(不透過代理)」或相應的更新項目;若網路環境確實需要代理,再選擇「更新訂閱(透過代理)」。
- v2rayN 匯入一次性連結:複製完整的逐行分享連結,在「伺服器」選單選擇「從剪貼簿匯入批次 URL」。先檢查匯入後的傳輸類型、TLS 與 SNI,再設為使用中的伺服器。
- v2rayNG 更新訂閱:前往「訂閱分組設定」,新增分組、填入 URL 並儲存,再返回清單執行「更新訂閱」。剪貼簿中的節點應使用新增選單內的「從剪貼簿匯入」,不要混用這兩種入口。
- v2flyNG 檢查相容性:使用訂閱或分享連結匯入功能前,先確認節點設定適用於 V2Fly 核心。若節點需要 Xray 專屬功能,應向服務商索取相容設定,無法只靠編碼轉換解決。
七、訂閱轉換與匯入失敗的常見問題
解碼後還是 vmess:// 加上一長串內容,是不是還沒解完?
外層訂閱清單已解碼完成。先依換行拆分節點,再單獨解碼某一條 vmess:// 後方的載荷並解析 JSON。不要再次將整份清單送進 Base64 解碼器,也不要把 VMess 分享物件直接當成核心設定。
JSON 可以開啟,為什麼用戶端顯示零個節點?
先檢查頂層鍵名。若有 inbounds、outbounds,內容可能是完整核心設定,應使用自訂設定入口;若是錯誤碼與說明,則應先修復訂閱存取問題。JSON 語法正確與訂閱格式受支援是兩回事。
複製後匯入失敗,應先檢查哪些地方?
檢查連結是否遭通訊軟體截斷、查詢字串中的 & 是否被替換為字面的 HTML 實體,以及是否混入全形冒號或引號。先用一條完整連結測試,確認節點詳細資料正常後,再匯入其他內容。
節點匯入成功卻無法連線,需要改用另一種訂閱格式嗎?
先核對位址、443 等實際伺服器連接埠、UUID、傳輸路徑、SNI 與核心支援情況,再查看連線記錄。10808 這類本機監聽連接埠不能填在遠端連接埠欄位。欄位已正確匯入時,重新編碼通常無法排除連線故障。
可以把訂閱交給線上工具轉成 JSON 嗎?
建議優先使用本機工具與用戶端的匯出功能。訂閱 URL 與節點驗證資訊都應視為敏感資料;若已外洩,請在服務商管理頁面重設訂閱權杖,並依服務商規定更換節點憑證,之後更新各裝置儲存的網址。
最後可依四個步驟檢查:查看回應本文、辨識格式層級、核對節點欄位、確認核心運作。若想了解 TLS、出站與路由術語,可參閱術語手冊;若已完成匯入仍無法連線,再依疑難排解檢查記錄與網路設定。