1294 字
6 分鐘

Cloudflare 1.1.1.1 DoH JSON 變了怎麼辦?先避免硬編碼 data 格式

如果你的程式把 Cloudflare 1.1.1.1 的 DoH JSON response 當成固定字串格式,最近可能遇到一種很難從 HTTP status 看出來的錯誤:查詢成功了,但 data 的內容和原本測試 fixture 不一樣,解析器因此失敗。

Cloudflare 在 2026-07-28 公告正在調整 application/dns-json 的 data 顯示方式,而且 rollout 期間可能同時收到舊格式與新格式。這次不是 endpoint 被移除,而是 JSON schema 本來就沒有正式 RFC;關鍵修正是不要把 data 當成可以跨 provider、跨時間固定不變的 wire format。

先確認是資料格式差異,不是 DNS 查詢失敗#

先保留 HTTP 狀態、JSON 的 Status、record type 和 data,不要只記錄最後的解析例外:

Terminal window
curl -fsS \
-H 'accept: application/dns-json' \
'https://cloudflare-dns.com/dns-query?name=cloudflare.com&type=HTTPS'

成功 response 仍然可能是 JSON,例如:

{
"Status": 0,
"Answer": [
{
"name": "cloudflare.com",
"type": 65,
"TTL": 300,
"data": "1 . alpn=h3,h2 ipv4hint=..."
}
]
}

這裡要分開看三個層次:

  1. HTTP 是否成功,例如 200。
  2. DNS response 的 Status 是否代表查詢成功。
  3. 你的程式是否能依 type 解讀 data。

前兩層都成功,第三層仍可能因格式差異失敗。用 type 而不是只看文字內容判斷 record 類型,才能把問題定位在解析邏輯。

Cloudflare 這次改了哪些 data 格式#

官方公告列出三組變更:

  • CAA、NAPTR、RP、IPSECKEY、SVCB、HTTPS、TLSA、SSHFP、OPENPGPKEY 等額外 record,可能從 RFC 3597 的泛用十六進位格式改成標準 presentation format。
  • RRSIG、DS、CDS、DNSKEY、CDNSKEY 的 DNSSEC algorithm identifier 改用數字,例如 RSASHA256 對應 8;DS digest type 也改用數字,例如 SHA-256 對應 2。
  • HINFO 的 character-string 會個別加上引號,避免值內有空白時產生歧義。

另外,Cloudflare 明確提醒 rollout 期間可能同時拿到新舊格式。因此只替一個 fixture 加判斷,並不能保證其他 record type 已經完成遷移。

解析程式要依 record type 分流#

如果你的需求只是列出 DNS 查詢結果,至少先保留型別與原始資料,讓日後能回放問題:

function normalizeAnswers(payload) {
return (payload.Answer ?? []).map((record) => ({
name: record.name,
type: record.type,
ttl: record.TTL,
data: record.data,
}));
}

接著依 type 對應到 DNS library 或自己的 parser。不要寫成「只要把 data 用空白切開,固定取第 2、3 欄」;SVCB、HTTPS、NAPTR 和 DNSSEC record 的欄位規則不同,呈現格式也可能在 rollout 中改變。

可以把測試拆成以下幾組:

測試案例要驗證的邊界
A、AAAA、CNAME一般 address 與 target 的基本解析
CAA、SVCB、HTTPSquoted value、parameter 與空白分隔
RRSIG、DS、DNSKEYalgorithm 與 digest type 使用數字
舊 fixture 與新 fixturerollout 期間 parser 能否安全拒絕或相容

若你不需要把 record 內容轉成自己的結構,最安全的選擇是把 data 視為供顯示或記錄的文字,不要再對它做沒有規格依據的二次解析。

重要用途改用 DoH wireformat#

Cloudflare 文件將 JSON 定位為方便查詢的格式,並指出關鍵用途應使用符合 RFC 1035 的 DNS wireformat。wireformat 的請求不是把 name、type 放在 JSON 裡,而是先由 DNS library 產生二進位 query:

Terminal window
# <base64url-encoded-dns-query> 要由 DNS library 產生
curl -fsS \
-H 'accept: application/dns-message' \
'https://cloudflare-dns.com/dns-query?dns=<base64url-encoded-dns-query>' \
--output response.bin

若使用 POST,則將二進位 query 放在 request body,並使用 content-type: application/dns-message。回應也要交給支援 DNS wireformat 的 library 解碼,不要把 binary response 當 JSON 讀取。

這個分流適合:

  • DNSSEC 驗證或稽核。
  • 需要穩定欄位結構的監控與資料管線。
  • 不希望被特定 resolver 的 JSON 顯示習慣綁住的服務。

使用 wireformat 不代表所有錯誤都消失;你仍要處理 HTTP 400、413、415、504,以及 DNS response code。

一個可回滾的遷移流程#

不要直接把 production parser 改成「接受任何字串」。可以按這個順序處理:

  1. 把目前 JSON response、查詢參數、HTTP status 和查核日期存成 fixture。
  2. 依 type 補上 CAA、SVCB、HTTPS、DNSSEC 的新舊資料案例。
  3. 對只需要穩定結構的流程,改評估 wireformat。
  4. 先在 shadow 或測試流程同時執行新舊 parser,記錄差異但不改主流程。
  5. 確認監控能區分「DNS 查詢失敗」和「解析器拒絕未知格式」後,再切換 production。

結論是:Cloudflare 1.1.1.1 的 DoH JSON 仍可用,但 data 不應被當成固定 schema。查詢型工具可以保留 JSON 並依 record type 驗證;關鍵資料管線則應使用 wireformat,或至少把格式差異納入測試與可觀測性。

常見問題#

Q: Cloudflare DoH JSON API 是不是要停用了?#

A: 不是。Cloudflare 仍提供 GET JSON 查詢;這次公告是 data 的格式 rollout,而且可能同時出現新舊回應。真正需要調整的是依賴固定文字格式的 parser。

Q: 所有 DNS record 的 data 都會一起改嗎?#

A: 官方列出的是額外 record、DNSSEC 相關 record 和 HINFO 的格式變更。不要假設每種 record 都改了,也不要假設尚未列出的格式永遠不會變;程式仍應依 type 和官方文件處理。

Q: JSON 和 wireformat 要怎麼選?#

A: 只是查詢或顯示結果時,JSON 比較容易使用;若是 DNSSEC、監控、稽核或需要穩定結構的資料管線,優先使用 wireformat,讓 DNS library 解碼標準格式。

參考資料:

Cloudflare Changelog:Improved DoH JSON formatting

Cloudflare Docs:Using JSON

Cloudflare Docs:DNS Wireformat

RFC 1035:Domain Names - Implementation and Specification

Cloudflare 1.1.1.1 DoH JSON 變了怎麼辦?先避免硬編碼 data 格式
https://laplusda.com/posts/cloudflare-doh-json-data-format/
作者
Zero
發佈於
2026-08-07
許可協議
CC BY-NC-SA 4.0
這篇文章有幫助嗎?

回報錯字、失效連結,或告訴我你想看的延伸主題。