部落格 分享機制

用 URL Hash 分享 JSON:不上傳伺服器的原理、限制與用法

同事說「你那邊 JSON 一格式化就對,我這邊報錯」。把文件傳來傳去很煩,截圖又沒辦法繼續改。

URL Hash 分享把目前工具和輸入寫進網址列的#後面。對方打開同一條鏈接,瀏覽器在本地還原左右欄;普通頁面請求不會把這份資料發給伺服器。

這和「貼到某個線上格式化網站再點分享」不是一回事。後者通常會先把原文 POST 到別人的後端,再給你一個短鏈。 Hash 分享沒有這一步。

本文將說明:

先記住這一點:Hash 能用,是因為瀏覽器預設不把#後面發給伺服器。但這既不是加密,也擋不住聊天軟體把連結截斷。以下按「原理 → 編碼 → 長度 → 邊界」把這件事拆開。

URL Hash 分享是什麼

完整 URL 可以拆成兩段:伺服器會看到的部分,和只留在瀏覽器裡的部分。

https://jsonnote.com/json/format.html#data=eyJvayI6dHJ1ZX0=

請求發給伺服器 fragment / Hash(只留在瀏覽器)

DevBox 的「分享」做的是:把目前工具 id 和左側輸入編碼進 Hash,再把整段location.href複製到剪貼簿。對方打開後,頁面腳本讀location.hash,在他自己的瀏覽器裡還原工具和文字。

  1. 1
    你在瀏覽器裡點「分享」

    輸入先轉成 UTF-8,再編成 Base64,寫成#tool=&data=

  2. 2
    把完整 URL 發給同事

    對方打開同一網站後,頁面腳本讀location.hash

  3. 3
    在對方瀏覽器裡還原

    本地格式化、校驗或 Diff。伺服器只收到頁面本身,沒有這份 JSON。

這和把 JSON 處理放在瀏覽器裡是同一原則:計算發生在本地,分享也不經過我們的資料庫。隱私邊界寫在隱私權聲明第 3 節。

為什麼 Hash 不會上傳到伺服器

Fragment 不會進入 HTTP 請求

MDN 對 URL.hash 的說明WHATWG URL 標準裡的 fragment#之後是 fragment identifier。瀏覽器導航時,HTTP 請求的 path / query 不包含這段。

所以訪問日誌里通常只有:

伺服器日誌裡常見的請求行
GET /json/format.html HTTP/1.1

而不是:

Hash 不會出現在請求行裡
GET /json/format.html#data=……

這也是為什麼 Hash 適合「我不想讓網站存一份我的貼」,卻不適合當保密通道:資料仍在完整 URL 裡,只是預設不走這一跳網路。

和 Query String 的差別

寫法 例子 伺服器看不看得到 適合做什麼
Query ?tool=json-format&data=… 會。出現在請求行、反向代理程式和 CDN 日誌裡 需要服務端讀的參數
Hash #tool=json-format&data=… 普通頁面請求不會帶上 只給前端腳本用的狀態

如果有人把同樣的 Base64 放到?後面,效果看起來一樣,資料卻已經進了伺服器日誌。 DevBox 只寫 Hash,就是為了避開這一層。

另外:Referer 通常也不帶 fragment。你從分享頁點到外鏈,對方網站一般拿不到 Hash 裡的 JSON。這是瀏覽器預設行為,不是我們額外做的加密。

DevBox 的分享連結長什麼樣

點「分享」後,Hash 是一組URLSearchParams

DevBox 分享連結的 Hash 格式
#tool=json-format&data=<Base64>

tool

目前工具 id。打開連結後會切到對應工作區,而不是一律落到「JSON 格式化」。常見值包括json-formatjson-validatejson5json-pathjson-diff

只切換工具、不點分享時,網址列會更新成#tool=…不含 data。這是為了記住你在用哪個工具,不會把編輯器裡的內容寫進歷史記錄。

data

左側輸入的 UTF-8 文本,再做 Base64。實現上等價於:

JavaScript · 編碼
btoa(unescape(encodeURIComponent(input)))

encodeURIComponent是為了讓中文和 Emoji 能過btoa。還原時走相反路徑。這和 MDN 討論的Unicode 字串的 Base64 編碼是同一類問題。

編碼不是加密

Base64 的目的在於「任意位元組都能放進 URL」,不是「只有受信方能讀」。任何人拿到鏈接,都可以在控制台還原:

JavaScript · 還原流程範例
const data = new URLSearchParams(location.hash.slice(1)).get("data");
decodeURIComponent(escape(atob(data)));

也可以把data=後面的字串丟進本站的Base64 解碼。沒有口令,沒有一次性鏈接,也沒有過期時間。

一個完整範例

假設你在「JSON 格式化」裡輸入:

JSON · 左側輸入
{
  "name": "Ada",
  "role": "dev"
}

壓縮成一行後是 27 位元組:

JSON · 壓縮後
{"name":"Ada","role":"dev"}

UTF-8 → Base64 得到 36 個 ASCII 字元(這段裡面沒有+ / /,放進 URL 時不會再被百分號編碼延長):

Base64
eyJuYW1lIjoiQWRhIiwicm9sZSI6ImRldiJ9

完整 Hash:

完整 Hash
#tool=json-format&data=eyJuYW1lIjoiQWRhIiwicm9sZSI6ImRldiJ9

對方打開後看到同一段 JSON,可以繼續格式化、做JSONPath 抽取,或和自己的回應做 Diff。若原文其實是附註解的配置,應改用JSON5 解析再分享輸出,而不是把無法JSON.parse的文字直接丟給對方。

含中文時量更明顯。例如{"msg":"格式化后两边一致"}是 34 位元組 UTF-8,Base64 後 48 字元;其中的/=再被 URL 編碼,參數值會變成 54 字元。

連結會變多長

Hash 分享的硬限制不是「伺服器上傳上限」,而是整段 URL 還能無法完整送達對方瀏覽器

對一段近似純 ASCII 的 JSON,實測數量級如下(含tool=json-format&data=的膨脹後長度):

原文大約 編碼後 Hash 大約 經驗限制
200 B 330 字符 聊天軟體幾乎都能完整送達
1 KB 1.4 KB 多數 IM 沒問題,仍建議自己點開確認
8 KB 11 KB 瀏覽器通常能開啟;部分客戶端會截斷
32 KB 44 KB 不要指望微信 / 郵件原文轉寄還能用

Chrome 能消化很長的網址欄,但中間還有一層:IM、郵件、短鏈服務、二維碼。它們各自有更短的上限,而且很少告訴你「我把尾巴切掉了」。所以流程應是:

  1. 1
    點「分享」

    複製完整地址,不要只抄#後面一截。

  2. 2
    先在本機新標籤打開

    確認工具和輸入都在,再發給同事。

整份存取日誌、數兆的匯出文件,請本機貼上或點「下載」。 Hash 分享解決的是「復現一小段輸入」,不是當網盤。

Hash 分享和其他方式比什麼

方式 數據去哪 對方怎麼接著乾 適合 不適合
URL Hash 停在雙方網址列 打開同一站點即可繼續處理 小段 JSON、復現報錯 金鑰、超大文件
聊天原文 聊天伺服器 再複製一次 幾行配置 進永久會話記錄的內部數據
截圖 圖片 只能看,不能 parse 讲结构 還要繼續格式化 / Diff
附件 / 网盘 第三方存储 下载后再贴 大文件 想避免多一份副本
在线 Paste 别人的后端 打开短链 需要公開、長期存放 任何不該離開本機的內容

團隊裡若已經有內網 paste 或工單附件,大段日誌走原有通道更穩。 Hash 的价值是:同一條連結同時帶著「用哪個工具」和「輸入是什麼」,對方不用猜你點的是格式化還是校驗。

使用時必須記住的邊界

涉及真實隱私時,用離線或內網工具。這和「網站有沒有登入框」無關。

常見問題

URL Hash 分享是什麼?

把目前工具和輸入編碼進網址列#後面。對方打開同一網站的同一條鏈接,瀏覽器在本地還原內容,而不把這份資料作為頁面請求發給伺服器。

Hash 裡的數據伺服器能看到嗎?

普通頁面請求不會把 fragment 發給伺服器,訪問日誌裡通常只有路徑。但這不等於保密:拿到完整連結的人都能解碼。

編碼和加密有什麼不同?

編碼(這裡是 Base64)保證文字能放進 URL,任何人都能反向還原。加密需要金鑰,沒有金鑰就不能讀。 DevBox 分享做的是前者。

Hash 分享可以用於金鑰或 Token 嗎?

不可以。連結一旦發出就無法收回,歷史記錄裡也還在。密鑰請走你們團隊的金鑰管理系統,不要進任何網頁網址列。

對方打開是空白的?

先检查 URL 是否在data=中間被截斷;再確認打開的是同一個 DevBox 站點,而不是只複製了#後面一截。超大文本请改用本机粘贴。

和 JSON 格式化、校验是什么关系?

分享只負責「原樣帶走當前輸入和工具」。格式化、文法校驗、JSON5、JSONPath、Diff 仍在對方瀏覽器裡本地執行。需要先看结构,用JSON 格式化;需要定位Unexpected token,用校驗JSON5

總結

URL Hash 分享本质上是:

本機工具狀態 + 可逆編碼 + 瀏覽器 fragment 不隨要求上傳。

它適合複現一小段 JSON 或配置,不適合當網盤,更不適合傳秘密。用對了,你和同事對著同一左右欄說話;用錯了,等於把明文貼進一條誰都能打開的地址。

← 返回博客