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 也值得認真看看。

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

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

做法怎麼送問題
GET參數全塞進 URL 查詢字串常卡在 2 ~ 8 KB 就爆(Proxy, CDN、瀏覽器各自不同)
PII(個資)還會留在網址,進瀏覽器歷史與 access log
POST複雜條件放 request bodySemantics 像「可能要寫入」,不是唯讀、也不是 Idempotent
斷線不敢自動重試,共享 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 傳輸。

也就是說:過去確實有「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 資料:跨域麻煩,而且現場還沒幾套 Server 認 QUERY。Request / Response 都是在瀏覽器模擬的;請看上面三個標籤,以及按 「模擬斷線後重試」 之後黃色便條紙的提示怎麼寫。

​ ​

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

先按「送出」,看標籤「不保證」、「不適合」;再按「模擬斷線後重試」,讀黃色便條紙的提示。POST 不保證冪等,Proxy 可能不敢幫你重送;若沒有跟後端溝通清楚,那 MES 系統有機會被計算成重複報工。這就是前面說 POST /search 能查,但整條請求路徑卻誤當成在寫資料的原因。

現在:HTTP QUERY(唯讀查詢)

同一包 body,換 QUERY 再試:先送出,標籤應變成三個「是」;再按重試,第二次 body 沒改會看到 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-01 單張(那用 GET /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 要一致

情境:應用在大型電商

大型電商(年訂單量百萬級以上、SKU(貨號、品號)十萬以上、多倉庫多通路)的後台與前台 API,「搜尋、篩選、分析」佔流量極高比例。2026 年前幾乎清一色 POST /search 或 GraphQL over 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 上本來就是讀取。

*促銷的試算與真正實務套用

營運後台要模擬:滿額折、會員折、通路券疊加後,購物車 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 擋、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 導致 Cache 投毒

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、反向代理、舊版 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