RFC 10008 HTTP QUERY 和 GET, POST 差在哪?

RFC 10008 HTTP QUERY 和 GET, POST 差在哪?

HTTP QUERY 是什麼?2026 年 6 月,IETF(Internet Engineering Task Force, 網際網路工程任務組)正式發布 RFC 10008《The HTTP QUERY Method》,在 HTTP Semantics(語意) 裡多了一個新 Method(方法)QUERY。我們每天上網用的 HTTP, DNS, TCP/IP 等底層協定就是 IETF 制訂出來的,這次多了一個專門給「複雜唯讀查詢」用的方法。

Backend Engineer(後端工程師)開發 API、或是大型電商後台做過「條件很多、篩選很複雜」的查詢,大概都踩過這個坑:GET 塞不進 URL,POST 的 Semantics 又不像在讀資料。那就用 POST /search 假裝在讀資料,這作法應該是每個後端 RD 都曾做過的事 XD;時至今日協定層終於給了一個正規解法囉~

這篇會講清楚:RFC 10008 / HTTP QUERY 是什麼、和 GET, POST 差在哪、實務上可以怎麼使用,以及 PM 為什麼要懂(若覺得內容太長,文末有 TL;DR 版本詞彙對照)。

QUERY 就像「帶 request body(請求本文) 的唯讀查詢」, 較 Safe(安全)、可重試、可 Cache(快取),不用再拿 POST 假裝只是在讀資料。

目錄

  1. RFC 10008 與 HTTP QUERY 方法
  2. QUERY 能做什麼?和 GET, POST 差在哪?
  3. 情境:應用在 MES 系統
  4. 情境:應用在大型電商
  5. 有沒有資安風險?該如何避免?
  6. 為什麼產品經理需要懂 HTTP QUERY 方法?
  7. 現在該不該統一採用 QUERY?實務採用建議
  8. (想直接抓重點請看這)常見問題 FAQ:HTTP QUERY(RFC 10008)
  9. 總結
  10. 詞彙對照:這篇文章反覆出現的術語

RFC 10008 與 HTTP QUERY 方法

RFC 10008 是 IETF HTTP 工作小組在 2026 年 6 月發布的 Proposed Standard(建議標準),作者包含 Julian Reschke(greenbytes), James M. Snell(Cloudflare), Mike Bishop(Akamai)。IANA 已將 QUERY 登記為 Safe(安全)Idempotent(冪等) 的 HTTP 查詢方法。

規格定義很直白:

Client(客戶端) 用 QUERY Request(請求) 目標資源,以 Safe(安全)Idempotent(冪等) 的方式處理 request body(請求本文) 裡的內容,並把處理結果放在 Response(回應) 裡。Semantics(語意) 上接近 POST「可以帶 body」,但 QUERY 可以自動重試,不必擔心重送造成狀態被改一半。

和既有方法的關係,可以參考以下的整理:

屬性GETQUERYPOST
安全(不改變目標資源狀態)不保證
冪等(可安全重試)不保證
可快取僅限特定 POST 快取情境
Request Body無定義語意預期有 body,body 本身就是查詢預期有 body
查詢條件放哪URL 查詢字串Request BodyRequest Body

規格還定義了幾個配套機制,這在 PM 和 RD 協作時會用到(溝通起來比較沒有隔閡):

  • Content-Type 必填Server(伺服器) 若缺漏或與內容不一致,必須回 4xx。
  • Accept-Query Response Header(回應標頭):Server 可宣告支援哪些查詢格式(例如 application/json, application/sql)。Client 也可先送 OPTIONSHEAD 試試看支不支援。
  • Content-Location / Location:可把「查詢結果」或「查詢本身」綁成 URI(Uniform Resource Identifier,統一資源識別碼),之後用 GET 重取,不必再送一次 body。
  • Cache(快取)規則:QUERY Response 可快取,但 cache key(快取鍵)必須納入 request body,不能只靠 URL。
  • 錯誤 Response 有標準分工:格式不支援回 415、語法或欄位錯誤回 422(在下面會提到)。

這個標準經歷很長的路:最早可追溯到 2015 年的 individual draft,曾叫 SEARCH,2021 年改名 QUERY 來脫離 WebDAV 的包袱,2025 年 11 月 IESG 核准,2026 年 6 月正式成為 RFC 10008(標準化過程與文件狀態可在 IETF Datatracker 的 RFC 10008 頁 查看)。HTTP 通常 (根本) 不會異動,一變動絕對是大事;常跟 RD 協作的 PM,建議一起把 Semantics 與採用時機看清楚。

QUERY 能做什麼?和 GET, POST 差在哪?

過去要向 Server 做複雜搜尋或篩選,實務上 RD 通常只有兩條路:

做法怎麼送問題
GET參數全塞進 URL 查詢字串常卡在 2 ~ 8 KB 就爆(Proxy, CDN 與瀏覽器各自不同)
PII(個資)還會留在網址,進瀏覽器歷史與 access log
POST複雜條件放 request bodySemantics 像「可能要寫入」,唯讀與冪等都不保證
斷線不敢自動重試,共享 Cache 也不當成讀取

*GET 與 POST 各卡在哪

RFC 10008 列出了四個「把查詢塞進 URL」會遇到的問題:長度(實務常見約 2 ~ 8 KB 就爆,RFC 9110 只保下限 8,000 bytes)、編碼(結構化資料硬塞 URI 很浪費)、隱私(URL 比 body 更容易進 access log, 書籤, Referer)、Semantics(每種參數組合都像不同資源,Cache 與監控指標被切碎)。

過去的 Workaround(變通做法、臨時方案)是 POST /search。能查,但 Semantics 告訴 HTTP:「這可能會改狀態。」結果是:

  • 連線中斷時,Client 與 Proxy 不敢自動重試,因為在電商怕重送變成重複下單,MES 系統怕重送被誤判成重複報工或重複下達
  • 共享 Cache 預設不當成可重複使用的讀取
  • 監控與防火牆規則常把 POST 當「寫入操作」對待。

QUERY 把三件事放在一起:帶 body、唯讀 Semantics、可 Cache 可重試

*常見疑問:GET 不是本來就能帶 body 嗎?

HTTP 從來沒禁止 GET 帶 body 啊?技術上沒錯,但這條路不當成正式解法。

說法實際狀況
「規範禁止 GET 帶 body」不對。RFC 9110 說的是 GET 的 body 沒有通用 Semantics;有些實作會直接拒絕,也有 request smuggling(請求偽造) 的疑慮。
「GET 帶 body 可以當企業級解法」不建議。部分雲端 WAF(例如 AWS WAF)會擋帶 body 的 GET,而且關不掉這項檢查。
「所以大家才用 POST /search」,但是用錯方法湊合。
「QUERY 是多此一舉嗎?」不算。它是給「帶 body 的唯讀查詢」一個標準名字與 Semantics;JSON 傳輸本來就有,QUERY 補的是 Method 語意。

過去確實有「GET 帶 body」這種 Workaround,也有「POST 假裝查詢」;現在多了 QUERY,是第三條正規路,也不會取代所有 GET。

另一個常見誤解是:「用 JSON 傳資料不是早就有了嗎?」POST 早就用 JSON 了。QUERY 補的是 HTTP Method Semantics:Safe, Idempotent, Cacheable,讓 Intermediary(中間層) 知道「這是唯讀查詢,不是在寫資料」。

*錯誤回應怎麼讀?415 與 422

Server 用 Accept-Query 告訴 Client 支援哪些查詢格式,例如:

Accept-Query: application/json, application/sql

Client 送錯時,RFC 10008 建議用不同狀態碼區分「格式不對」與「內容不對」:

HTTP Status Code白話解釋例子
415 Unsupported Media TypeServer 不認識這種查詢格式只收 application/json,你送 application/sql
422 Unprocessable Content格式看得懂,但查詢內容有誤JSON 合法,但 filter.status 欄位不存在
400 Bad RequestContent-Type 缺漏,或與 body 不一致宣稱 JSON 卻送純文字

BTW 在 PM 寫 PRD 或驗收時,可以直接要求 API 文件標明這三種情境的回應,減少「直接回 4xx」這種模糊地帶的說法。

*那典型的請求長什麼樣?
QUERY /api/work-orders/search HTTP/1.1
Host: mes.example.com
Content-Type: application/json
Accept: application/json

{
 "filters": {
 "status": ["Released", "InProcess"],
 "line": "A-吊飾線",
 "due_before": "2026-07-15"
 },
 "sort": [{"field": "priority", "dir": "desc"}],
 "page": {"size": 50, "cursor": null}
}

Released, InProcess 是 API 的欄位值,也就是生管口語的「已核准」「進行中」通常對應這兩種狀態。)

Server 若支援,可在 Response 裡附:

Accept-Query: "application/json"

讓 Client 知道這個路徑接受什麼查詢格式。

*互動範例:POST /search vs QUERY

上一節只能看靜態 HTTP 內資訊;這裡我寫簡單兩個範例來做對照,篩選條件用上述提到的同一份 JSON 資料(A 吊飾線、已核准與進行中、交期早於 7/15),也就是後面生管 Kevin 早會看板會下的那種查詢。兩個 Demo 只差在 Method(方法):一個還在用 POST 假裝查詢,一個改成 QUERY。

畫面上那三個備註標籤,這裡白話說明一下:

標籤白話
Safe(安全唯讀)這次操作不應該改系統的狀態:只是在問資料,不會改寫狀態
Idempotent(冪等)Wi‑Fi 不穩、多按幾次「重試」,結果跟按一次一樣
Cacheable(可快取)相同條件短時間可重新使用上次的結果,不用一直打後端

因為這裡沒接真實的 MES API 資料,所以 Request / Response 都是在瀏覽器模擬的;直接看上面三個標籤,以及按 「模擬斷線後重試」 之後黃色便條紙的提示怎麼寫。 ​ ​

過去:POST /search(假裝查詢)

一打開就會看到三個標籤是「不保證」、「不適合」:這是在說明 POST Semantics。先按「送出」,看 Request / Response;再按「模擬斷線後重試」,這時確認黃色便條紙。若沒有跟後端溝通清楚,MES 有機會被算成重複報工。這就是前面說 POST /search 能查詢沒錯,但整條請求路徑卻誤當成在寫資料的原因。

現在:HTTP QUERY(唯讀查詢)

同一包 body,把 Method 換成 QUERY。一打開就會看到三個標籤「是」,一樣是先標 Semantics。請先送出,再按「模擬斷線後重試」:第二次 body 沒改,Response 裡會看到 cache: "HIT"(快取鍵含 body,不只看網址)。後面生管 Kevin 看板 Wi‑Fi 不穩多按重新整理、品保儀表板短暫 Cache,講的就是這套,所以能不能真的快取還得看 Gateway 支不支援、權限怎麼切分。

所以 PM 在測試驗收時要確認的是:斷線能不能重試、相同條件能不能快取、API 文件寫的是讀還是寫。搜尋「查不查得到」這其實只是最基本的一層而已。

*什麼時候該用 QUERY,什麼時候不用?

這裡我就用 MES 工單作為範例說明。

要判斷用 GET 還是 QUERY,先看你有沒有確定的工單號

一個相對務實的分工會是這樣:GET 留給「已知 ID 的單筆資源」;QUERY 留給「條件很多的搜尋與篩選」。例如 MES 系統可以用 GET /api/work-orders/WO-01 拿單張工單,用 QUERY /work-orders/search 做複雜列表;至於舊的 POST /search 就繼續沿用,新功能再換成 QUERY 就好(尤其針對很多政府標案、金融類的產品,最怕的就是改 A 壞 B 這種狀況,對 RD 真的多一事不如少一事,千萬別去盧小工程部門 XDD)。

情境建議方法原因
單筆資源、已知 IDGETSemantics 最清楚(GET /api/work-orders/WO-01
簡單列表、參數少GETURL 夠用,生態系也最熟
複雜唯讀查詢、篩選 JSON 很大QUERY靠 body 承載,而且是 Safe, Idempotent, Cacheable
建立、更新、刪除、下單、報工POST / PUT / PATCH / DELETE會改狀態,不該用 QUERY
GraphQL 唯讀 queryQUERY(理想上)過去被迫用 POST,是因為 Semantics 不符合

情境:應用在 MES 系統

以皮克敏娃娃玩具廠的範例來說明(有興趣可以看看生管為什麼一直問工單?訂單 vs 工單差在哪?),這裡我以兩個可能最常碰到的情境來說明「若新模組或新看板要上 QUERY,會長什麼樣」。

*生管 Kevin 工單看板改用 QUERY

早會前生管 Kevin 盯著工單看板,要撈「A 吊飾線、已核准、本週要交、跟紅葉有關、優先序高」工單資訊。單張 WO-01GET /api/work-orders/WO-01 就好;這批是複合條件列表。七、八個條件硬塞 URL 動輒幾千個字元,各層 Proxy 還可能截斷;RD 當初只好做成 POST /api/work-orders/search,語意卻像在下指令。

若這支 API 改成 QUERY /api/work-orders/search,篩選、排序、分頁全放 body,Kevin 會注意到:廠內 Wi‑Fi 不穩時,重新整理看板多按一次,不用再猜「剛剛到底有沒有查到」。看板是製造廠內 Web(打內網 API),對外跨網域不在這段範圍;上線前仍要實測 Gateway 是否認 QUERY(參考下面實務採用建議)。早會前十個人開同一頁,Gateway 在權限範圍內可短 TTL(Time-to-Live, 快取存留時間) Cache 的話,也不會把 MES 打到卡住;篩選條件也不會整串印在 access log 裡。

*品保拉 8D Report 前的異常事件分析

上週 A 線「治具未到」在現場鬧了兩天,品保要寫 8D Report(八大步驟問題解決報告),也就是工廠處理品質異常、客訴時常用的結構化改善報告,這時得先把異常工單撈齊:哪幾張、卡在哪一站、原因代號怎麼分、嚴重度怎麼排。條件裡 AND / OR 混在一起,用 GET 會變成一條沒人想維護的查詢字串;但改用 POST,防火牆和監控又會誤以為有人在寫入資料。

若改送 QUERY /api/exceptions/search,時間區間、原因代號、產線、結案與否都寫在 body。主管重新整理異常儀表板,相同條件在內網、依角色授權的前提下,可以 Cache 三十秒到一分鐘。若要再往下撈(料號 PKM-RED-001、途程 v3、製程 20 到 30 之間出現過某治具的工單),巢狀更深,一樣塞 body 比硬是用 URL 還合理。報告裡還能貼 Response 回的 Content-Location,下次打開也不用重送整包條件。

-其他 MES 場景一覽

場景典型 API 路徑為何 QUERY 優於 POST / 長 GET
工單複合搜尋/api/work-orders/search條件多、要分頁排序,URL 塞不下
途程追溯/api/traceability/query巢狀條件多,Response 可附 Content-Location 快照
異常事件分析/api/exceptions/search唯讀分析,適合短時間 Cache、可安全重試
OEE 儀表板/api/metrics/oee/query讀取很頻繁,適合短 TTL Cache
跨廠在製/api/cross-plant/wip-searchbody 大,跨 Gateway 時 Semantics 要一致

情境:應用在大型電商

電商後台與前台只要條件一多,「搜尋、篩選、試算、分析」這類的唯讀 API 就很容易卡在:GET 塞不進 URL,於是改成 POST /search,或把 GraphQL 也掛在 POST 上,下面是三個常見的場景:

*客服高峰查訂單

客服後台依「手機末三碼、日期區間、付款狀態、物流狀態、是否含客訴標籤」等條件來查訂單,尖峰時請求很密。查詢條件含個資,放 URL 會進 access log,合規風險高;走 POST 又難 Cache、難重試。 查詢條件放 body、不進 URL log,相同條件短時間可 Cache(授權與快取範圍可以查看資安那個區塊的說明)。如果有法務剛好詢問也能更快掌握到重點:查詢條件在 body、操作是安全的唯讀,降低 log 外洩的疑慮。

*結帳前庫存試算

使用者下單前要算「各倉可售量、運送中庫存、預留量、門市可取貨」,B2C 與 B2B 通路規則還不同。一次查詢常帶數十個 SKU、多倉庫、多通路規則,但 payload 也大;手機 APP 在網路不穩時又需要不斷重試。

QUERY /inventory/availability 批次帶 SKU 列表與通路 context。結帳前的讀取可以安全重試,Client 不必像 POST 那樣擔心「重送會不會多扣庫存」,因為 Semantics 上本來就是讀取。

*促銷情境:試算 vs 真正實務套用

營運後台要模擬:滿額折、會員折、通路券疊加後,購物車 12 件商品各是多少錢,但還沒真正套用優惠。試算與「套用優惠」必須在語意上分開;過去常用 POST 做試算,工程師容易做錯。

試算走 QUERY(唯讀、可重複執行),真正套用走 POST / PATCH。PM 寫 PRD 時畫界就很清楚:試算是 QUERY,套用是 POST,驗收也比較好核對。

-其他電商場景一覽

場景典型 API 路徑流量特性QUERY 帶來的差異
目錄多條件篩選/catalog/products極高 QPS(每秒請求數)body 承載得住,邊緣有 Cache 空間,Semantics 也對
個人化推薦/recommendations/feed高 QPS + 大 bodycache key 可含 body hash,讀取很頻繁
營運分析/analytics/reports/run大 payload監控上不必再假裝是寫入
B2B 採購查詢/b2b/purchase-orders/search複雜權限大客戶文件可寫明 安全唯讀 Semantics,方便 Cache 與重試

有沒有資安風險?該如何避免?

RFC 10008 本身設計合理,但整個生態系有跟沒有上就很難說了,因為風險多半出在「周邊設備還當它是陌生 Method」或「Cache 實作錯誤」。

-WAF(防火牆)與 API Gateway 檢查缺口

許多防火牆規則針對 GET / POST / PUT / DELETE 調校。攻擊者對 POST /search 會被 SQL 注入規則擋下,換成 QUERY /search 同一包惡意請求內容卻可能通過。

實務上可以先在 Staging(預發布 / 測試環境)同一包惡意內容分別測 POST 與 QUERY,看防火牆反應一不一樣;再更新 Method 的 allowlist(允許清單),讓 QUERY 的 body 跟 POST 一樣嚴格檢查(SQL 注入、跨站腳本(XSS)、命令注入)。過渡期也建議把外網 QUERY 流量納入監控,這樣異常時就能告警。

如果真的要測試,可以參考以下的 curl 範例。記得喔!!只能拿來打 Staging,不要拿 Production 環境來測。路徑沿用前面的工單搜尋,方便跟前面例子一致;實際請改成你們自己的 Staging 網址。這是對照測的方法:用來比較 POST 與 QUERY 的攔截是否一致,不保證每套 WAF 都會出現這種缺口

步驟 1:準備同一份「會觸發 SQL 注入規則」的 body

重點只有一個:POST 與 QUERY 用同一包 JSON,只差 Method。 下面 keyword 裡的字串,是常見會被 WAF 特徵規則擋下的寫法,用來確認規則有沒有真的掃到 body;別拿去把資料庫搞到掛掉 …

STAGING='https://staging.mes.example.com/api/work-orders/search'

cat > /tmp/waf-payload.json <<'EOF'
{
  "filters": {
    "keyword": "' OR '1'='1"
  },
  "page": { "size": 10 }
}
EOF

步驟 2:先用 POST 打一次(對照組)

curl -sS -o /tmp/waf-post.body -w 'POST status=%{http_code}\n' \
  -X POST "$STAGING" \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json' \
  -d @/tmp/waf-payload.json

通常會被擋(例如 403),但以你們 WAF 實際回應為準;有的會回自訂狀態碼,或直接把請求丟進應用層。先把「這條路徑對 POST 惡意內容怎麼反應」記下來,後面才有對照基準。

步驟 3:換成 QUERY,body 一字不改再打一次

curl -sS -o /tmp/waf-query.body -w 'QUERY status=%{http_code}\n' \
  -X QUERY "$STAGING" \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json' \
  -d @/tmp/waf-payload.json

步驟 4:把兩邊結果擺在一起看

結果代表什麼下一步
POST 擋、QUERY 也擋(例如都是 403)Method 換了,body 檢查仍跟 POST 一樣嚴格過關;有空再補跨站腳本、命令注入特徵各測一次
POST 擋、QUERY 放行(200 或進到應用層)缺口:規則還只綁在舊 Method立刻把 QUERY 寫進允許清單,並讓 QUERY body 套用與 POST 相同規則,再重測
兩邊都放行這條路徑根本沒在掃 body,或特徵沒吃到 JSON 欄位先把 WAF / Gateway 的 body 檢查修好,再談上 QUERY
QUERY 回 405中間層還不認 QUERY先處理基礎設施(參考下面「基礎設施不認識 QUERY」);等 Method 通了,再回來做這輪 WAF 對照

步驟 5:規則修好後,把步驟 2、3 再跑一次

驗收其實很單純:同一包內容,POST 與 QUERY 的攔截結果要一致。 過渡期也可能在監控上盯「外網 QUERY 被放行、但內容看起來像注入」的流量,避免規則漏了卻沒人發現。

-cache key 未含 body,快取可能被塞錯資料

QUERY Response 可 Cache,但 RFC 要求 cache key 必須納入 request body。若 CDN 或廠內 Cache 只 hash URL,攻擊者可能讓其他人拿到錯誤的查詢結果。

Cache 層應把 request body 完整雜湊 進 cache key,過渡期寧可保守;若要做 JSON key 排序這類正規化,測試要嚴格。含 PII 的查詢預設不 Cache,或只開 private cache、極短 TTL。

-CSRF 與 Safe Method 的誤解

QUERY 標記為 Safe(安全唯讀),傳統 CSRF 中間層可能不檢查。若工程師在 QUERY handler 裡偷偷寫入 side effect(例如更新「最後查詢時間」),可能會留下 CSRF 盲點。

QUERY handler 必須真正唯讀;任何副作用改用 POST。端點只要有狀態變更,不論 Method 名稱都要做 CSRF 保護。HTML form 發不出 QUERY,傳統 forged form 風險低,但 fetch 跨域仍要處理 CORS。

-CORS 與跨域 Preflight(預檢請求)

QUERY 不在 CORS safelisted method 清單裡,跨域 JavaScript 一定會 Preflight OPTIONS。CDN 或 Gateway 若對 OPTIONS 處理不一致,可能出現「以為能查、其實被擋」。

Access-Control-Allow-Methods 要明確列出 QUERY;瀏覽器 fetch 跨域 QUERY 要從頭到尾實測 Preflight。副作用是較難用「看起來像 GET」繞過 CORS body 限制;多數情況這反而是好事。

-基礎設施不認識 QUERY 導致行為異常

部分 CDN, Reverse Proxy(反向代理), 舊版 Load Balancer(負載平衡器)可能對未知 Method 回 405、拿掉 body,或錯誤改寫 Method。越「聰明」的 Intermediary(中間層),越可能用舊規則處理新方法。老舊 Gateway、防火牆能不能認 QUERY,上線前是個謎,不能假設規格出了就每一層都通。

實務上有人曾用 GET 帶 body 繞過 URL 長度,但 AWS WAF 會直接擋;這也是為什麼需要 QUERY,因為繼續靠 Workaround 過不了這關。

上線前用 curl 從外網與內網各打一次 QUERY;稽核防火牆 / Gateway 的 method allowlist;Client 過渡期可先 QUERY,收到 405 再 Fallback POST(可參考下面 Client 相容)。內網若還要備援才評估 X-HTTP-Method-Override: QUERY,但實務上其實不太容易。

-log 與個資

body 不進 URL log 是優點,但若應用自己把 body 全寫進 log,個資外洩風險仍在。查詢 access log 要遮住敏感欄位,只記 filter 摘要或 hash;客服、訂單查詢類 API 建議做欄位級遮罩。

-資安檢查清單(和 RD 們一起確認)

檢查項通過標準
WAFQUERY body 比照 POST,一樣嚴格檢查
Cachecache key 含 body hash
CSRFQUERY handler 零副作用
CORSAllow-Methods 含 QUERY,Preflight 實測要過
Gateway外網 QUERY 不能拿掉 body,也不能誤改 method
logbody 遮罩,個資不寫明文

為什麼產品經理需要懂 HTTP QUERY 方法?

它會直接影響 PRD 怎麼寫、API 文件怎麼訂、驗收怎麼測

過去 PRD 寫「搜尋 API」,RD 可能會預設 POST, QA 問能不能重試、資安問 POST 要不要做 CSRF。實務上常卡在同一件事:到底用 GET query 還是 POST query? 所以有了 QUERY 之後,API 文件可以寫清楚 「唯讀複雜查詢 = QUERY」,這樣就不用再吵 Method 名稱了 XD

*查詢跟寫入,可以分開寫

PRD 與 API 文件可以寫清楚:

  • 查詢、試算、分析用 QUERY(安全唯讀、可重試、可快取)
  • 建立、更新、套用用 POST / PUT / PATCH

減少「明明只是查資料,為什麼不能重試」的返工。

*複雜篩選不用再辯 URL 長度

業務說「篩選條件要再加五個維度」時,多半已超出 GET 合理範圍;QUERY 是協定層該走的路,所以不用再叫 RD 硬塞 URL。

*非功能需求(NFR)寫得更準確
NFR沒 QUERY 時有 QUERY 時
重試「Client 自行處理」模糊帶過可要求「QUERY 必須 Idempotent 重試」
CachePOST Cache 需特例說明可寫「相同 QUERY 可 Cache N 秒」
合規查詢條件進 URL log可要求「查詢條件僅在 body」

*驗收清單比較好列

產品驗收時可要求:

  • 相同查詢條件重送兩次,結果一致、無重複副作用;
  • 網路中斷後自動重試,不產生幽靈寫入;
  • WAF(防火牆)對惡意查詢 payload 與 POST 行為一致;
  • 跨域前端(若有)Preflight 行為符合預期。

現在該不該統一採用 QUERY?實務採用建議

RFC 10008 雖然是正式標準、規格也沒問題,但實務上卻常是「Intermediary(中間層)還沒準備好,所以應用程式碼再新也沒用」,以下來看看截至 2026 年以來:

層級現況
協定RFC 10008 已發布,IANA 也已登記
瀏覽器fetch 可以下 QUERY,但跨域會多一次 OPTIONS,很多 CDN, Proxy 還會擋
Client(非瀏覽器)curl 可用 -X QUERY;Node.js 22+ 也已能解析
框架Rails, Django, Spring 多還在 PR 階段;ASP.NET 預覽版走得比較前面
CDN / 企業 Proxy部分節點不認 QUERY(405、拿掉 body、誤改 method),也可能直接擋 GET+body
老舊設備舊版 Gateway、廠內代理、嵌入式 client 常回 405 或拿掉 body

*第一道牆:Intermediary(中間層) 往往比應用程式更早擋下來

很多團隊以為「我們 API 已支援 QUERY 就能上線」,但 Request 路徑上還有企業 Proxy, CDN, WAF, Load Balancer。RFC 出了,不等於請求路徑上每一層都認得 QUERY;實務問題常常卡在基礎設施,業務程式碼反而比較後段才出事。

這對 MES 特別真實:廠內 Gateway、舊版介面閘道、客戶 SI 維護的 Reverse Proxy,都可能比你的 MES 核心更晚升級。上線前請從外網與內網各打一次 QUERY,比對回應是否一致。

*Client 相容:QUERY 優先,405 再 Fallback POST

過渡期 Client 策略可以寫進 PRD:先以 QUERY 送出查詢(body 不變);若收到 405 Method Not Allowed(或你們定義的「不支援 QUERY」訊號),自動改以 POST 重送同一 bodyFallback(備援));兩條路徑的 Response 格式應一致,方便 QA 對照。

要心裡有數:掉進 Fallback POST 時,語意又變回 POST。路徑上的節點不一定敢自動重試、共享 Cache 也不一定當成讀取;Fallback 只保證「先能查」,還不能享有 QUERY 的全部好處。目標仍是讓 QUERY 在每一層 Intermediary 都通過,逐步減少 Fallback 比例。

這條路徑通常比依賴 X-HTTP-Method-Override: QUERY 更適合當預設相容方案,原因在於:

作法好不好做說明
QUERY,405 再 Fallback POST較好做邏輯在 Client,不靠 Server middleware;邊緣看到的是標準 POST。
但 Fallback 這段仍受 POST Semantics 限制,Cache 與重試優勢會打折
X-HTTP-Method-Override較不好做要 Server 解包,邊緣永遠只見 POST。
全程都難發揮 QUERY 的 Cache 與 Semantics 優勢,稽核也不容易一眼看出原本是 QUERY

Override 比較像內網、條件比較能掌握時的備援405 Fallback POST 則比較像對外、跨多層基礎設施時較穩的作法。兩者可以並存,但若只能選一個寫進產品規格,多數情境會優先寫前者。

(想直接抓重點請看這)常見問題 FAQ:HTTP QUERY(RFC 10008)

-HTTP QUERY 是什麼?

HTTP QUERYRFC 10008(2026 年 6 月)定義的新 HTTP Method:把查詢條件放在 request body,語意上仍是唯讀(Safe)、可重試(Idempotent)、可快取(Cacheable)。白話說,就是「帶 body 的 GET」,專門解決複雜篩選塞不進 URL、又不該假裝成 POST 寫入的問題。

-QUERY 和 GET, POST 有什麼差別?

GETQUERYPOST
查詢條件放哪URLrequest bodyrequest body
是否安全唯讀 / 冪等不保證
適合場景已知 ID、參數少複雜唯讀搜尋建立、更新、下單等會改狀態

-現在該不該把 POST /search 改成 QUERY?

舊的能跑就別急著全改。 新功能、新看板可以優先用 QUERY;上線前一定要實測 Gateway, CDN, WAF 是否認得這個 Method。過渡期可用「先 QUERY,收到 405 再 Fallback POST」。

-HTTP QUERY 有資安風險嗎?

有,而且多半出在基礎設施還沒跟上。協定本身沒有特別「比較危險」;常見風險包括:中間層誤擋或誤放行、Cache key 沒納入 body 讓別人拿到錯的查詢結果、WAF 規則仍只盯 POST。權限、限流、個資不要進 URL,這些原則跟以前一樣都要做。

-產品經理為什麼要懂 HTTP QUERY?

因為它會影響 API 文件、快取策略、重試行為與上線風險。PM 若只寫「做一支搜尋 API」,RD 可能繼續用 POST /search;若規格寫「複雜唯讀用 QUERY、已知 ID 用 GET」,協作成本與資安問題會比較清楚。

總結

複雜的唯讀查詢,現在有正式 Method,不必再拿 POST /search 假裝在讀資料。

實務上就兩個重點:已知 ID 用 GET,條件一堆才考慮 QUERY;新功能可以試試,舊的 POST /search 能跑就別急著改。Gateway, 防火牆認不認 QUERY,上線前要從外網、內網各實測一次。

詞彙對照:這篇文章反覆出現的術語

原文中文簡短白話說明
HTTP超文字傳輸協定瀏覽器、App 跟伺服器說話用的協定;GET / POST / QUERY 都是它的 Method
RFC請求意見稿 / 標準文件Request for Comments:IETF 發布的網際網路標準文件,例如 RFC 10008
IETF網際網路工程任務組制訂 HTTP, DNS, TCP/IP 等底層協定的組織
IANA網際網路號碼分配局負責登記 HTTP Method 名稱與屬性(例如 QUERY 是 Safe + Idempotent)
Proposed Standard建議標準IETF 標準軌道上的正式階梯之一;RFC 10008 以此狀態發布
API應用程式介面系統之間約定好的呼叫方式;這篇多半指 HTTP API
URL網址URI 的一種,常出現在瀏覽器位址列與 access log
URI統一資源識別碼指到某個資源的識別字串;URL 是 URI 的一種Content-Location 可能回完整 URL,也可能是 /api/... 這種相對路徑
JSONJSON常用的結構化資料格式;QUERY 的 body 很常是 JSON
SQLSQL資料庫查詢語言;也可當 QUERY 的一種查詢格式(看 Server 支不支援)
GraphQLGraphQL一種 API 查詢語言;唯讀 query 理想上可用 QUERY,過去常被迫用 POST
Client客戶端發出 HTTP 請求的那一端(瀏覽器、App, curl, MES 整合程式)
Server伺服器接收請求、回傳結果的那一端(API, Gateway 後面的應用)
Request請求從 Client 送到 Server 的一包 HTTP 訊息
request smuggling請求偽造前端 Proxy 與後端 Server 對「一個 Request 到哪裡結束」解讀不一致時,
攻擊者可能在同一條連線裡夾帶第二個隱藏請求,繞過 WAF(防火牆)或汙染 Cache;GET 帶 body 這類邊界模糊的做法更容易踩到
Response回應Server 回給 Client 的結果,含狀態碼與 body
Method方法HTTP 動詞(如 GET, POST, QUERY),決定「這是在讀還是在寫」
GETGET 方法讀取資源;條件通常放 URL,Safe、冪等、可快取
POSTPOST 方法可帶 body,但不保證唯讀或冪等;過去常被拿來假裝搜尋
QUERYQUERY 方法RFC 10008 定義的唯讀查詢 Method,帶 body 但不改狀態
OPTIONSOPTIONS 方法常拿來探路或做 CORS Preflight,問 Server「允不允許 QUERY」
Semantics語意這個 Method 在協定上代表什麼意思:讀取、寫入、能不能重試
Safe安全唯讀不應改變 Server 上的資源狀態;QUERY 與 GET 都屬 Safe
Idempotent冪等重送同一請求,效果應與送一次相同;斷線可安全重試
Cache / Cacheable快取 / 可快取相同請求可暫存結果,下次不必再打後端
request body請求本文Request 裡承載資料的主體;QUERY 把查詢條件放這裡
payload負載 / 請求內容常跟 body 混著講:這次請求實際帶過去的資料內容
Header標頭Request / Response 的 metadata,例如 Content-Type, Accept-Query
Content-TypeContent-Type 標頭告訴 Server body 是什麼格式;QUERY 缺了或對不上要回 4xx
Accept-QueryAccept-Query 標頭Server 宣告接受哪些查詢格式(如 JSON, SQL)
Content-LocationContent-Location 標頭指向「這次查詢結果」的 URI,之後可用 GET 重取
LocationLocation 標頭這裡常指「查詢本身」的 URI,之後用 GET 可重跑查詢
cache key快取鍵快取系統辨識「是不是同一個請求」的 key;QUERY 必須含 body
TTL快取存留時間Time-to-Live:這筆快取要留多久;時間一到就失效,下次要重查
hash雜湊把 body 算成固定長度指紋,常拿來組 cache key,避免只靠 URL
access log存取紀錄Server / Proxy 記下誰打了哪個網址;條件若放 URL 很容易被記進去
Proxy代理伺服器站在 Client 與 Server 之間轉發請求的設備(CDN 與企業 Proxy)
Reverse Proxy反向代理站在 Server 前面收流量、轉發進內網的 Proxy(廠內 Gateway 常見)
CDN內容傳遞網路把內容放到邊緣節點加速;也可能擋或不認新的 HTTP Method
Load Balancer負載平衡器把流量分到多台 Server;舊設備可能不認 QUERY
Intermediary中間層請求路徑上所有轉手節點:Proxy, Gateway, WAF, Load Balancer
GatewayAPI 閘道統一入口,負責路由、認證、限流、Method 轉發
WAF網頁應用程式防火牆在流量進入應用前檢查惡意 payload 的安全設備
allowlist允許清單只放行清單上的 Method / 來源;沒寫進 QUERY 就可能被擋
staging預發布 / 測試環境上正式站前用來驗證的環境;WAF 對照測請只打這裡
XSS跨站腳本把惡意腳本塞進網頁;WAF 常與 SQL 注入一起檢查
CORS跨來源資源共用瀏覽器跨網域呼叫 API 的安全規則
Preflight預檢請求跨域前先送 OPTIONS 問 Server「QUERY 可不可以」
CSRF跨站請求偽造騙瀏覽器代使用者送出非預期請求;傳統防護常只盯 POST 等「會改狀態」的 Method
side effect副作用查詢過程中偷偷改了狀態(例如更新「最後查詢時間」);QUERY handler 不該有
Fallback備援主要路徑失敗時改走備援,例如 QUERY 收到 405 改送 POST
X-HTTP-Method-OverrideMethod Override 標頭外表仍是 POST,用標頭宣稱「其實是 QUERY」;邊緣永遠只見 POST,較難當預設方案
Workaround變通作法規格沒寫清楚時的臨時解法,如 POST /search 假裝查詢
PII個人可識別資訊姓名、電話等敏感資料;不宜出現在 URL log
QPS每秒請求數Queries Per Second:一秒鐘打進系統多少次請求;數字愈高代表流量愈兇
MES製造執行系統管現場工單、開工與報工、報工完的系統;這篇用皮克敏廠當例子
SKU貨號 / 品號庫存與商品的最小管理單位;電商一次查詢常帶很多個
OEE設備綜合效率產線常用的效率指標;儀表板讀取很頻繁,適合短 TTL Cache
8D Report八大步驟問題解決報告品保處理品質異常 / 客訴常用的結構化改善報告

Ref

comments powered by Disqus