查看 Apigee Edge 說明文件。
前往
Apigee X說明文件。 資訊
問題
用戶端應用程式收到 HTTP 狀態碼 500 Internal Server Error
,
錯誤代碼 protocol.http.BadFormData
做為 API 呼叫的回應。
錯誤訊息
用戶端應用程式會取得下列回應代碼:
HTTP/1.1 500 Internal Server Error
此外,您也可能會看到下列錯誤訊息:
{ "fault":{ "faultstring":"Bad Form Data", "detail":{ "errorcode":"protocol.http.BadFormData" } } }
表單資料
進一步探討這個問題的疑難排解方法前,我們必須先瞭解什麼是表單資料。
表單資料是指使用者提供的資訊,通常是透過含有元素的 HTML 表單 例如文字輸入框、按鈕或核取方塊我們通常會以一系列的形式傳送表單資料 做為 HTTP 要求或回應的一部分
表單資料傳輸
- Content-Type: application/x-www-form-urlencoded
- 如果表單資料大小不大,則會以鍵/值組合的形式傳送資料,其中包含:
- 這兩個鍵中的字元均按照 表單 - 第 17.13.4.1 節
- 標頭
Content-Type: application/x-www-form-urlencoded
包含表單資料的要求範例:
curl https://HOSTALIAS/somepath -H "Content-Type: application/x-www-form-urlencoded" -d "username=abc@google.com&pasword=secret123"
- 鍵和值中的任何非英數字元
百分比編碼,也就是以三字元組成
%HH
,包含百分比符號後兩個十六進位數字 代表特定字元的 ASCII 程式碼 - 因此,雖然表單資料允許百分比符號 (
%
),但 會被解讀為特殊逸出序列的開頭。因此,如果表單資料需要 包含百分比符號 (%
) 的鍵或值,即應傳輸 例如%25,
,代表百分比符號的 ASCII 程式碼 (%
) 字元。
- 如果表單資料大小不大,則會以鍵/值組合的形式傳送資料,其中包含:
- Content-Type:multipart/form-data
如果您想要傳輸大量二進位資料或包含非 ASCII 文字的文字 字元,那麼您可以使用
Content-Type:
multipart/form-data,詳情請參閱 Google 表單 - 第 17.13.4.2 節
可能原因
只有在符合下列所有條件時,才會發生這個錯誤:
- 用戶端傳送至 Apigee Edge 的 HTTP 要求包含:
Content-Type: application/x-www-form-urlencoded
和- 使用百分比符號 (
%
) 或百分比符號的表單資料 (%
) 後接無效十六進位字元,不符合規定 表單 - 第 17.13.4.1 節。
Apigee Edge 中的 API Proxy 會讀取包含任何字元的特定表單參數 「禁止」用於透過 ExtractVariables 提出的要求,以及 assignMessage 政策。
舉例來說,如果表單資料包含照原樣的百分比符號 (
%
),但沒有 編碼) 或百分比符號 (%
),後面接著任何無效的十六進位 就會發生此錯誤。以下是導致這個錯誤的可能原因:
原因 說明 適用的疑難排解操作說明 要求中的表單參數包含不允許使用的字元 用戶端在 HTTP 要求中傳遞的表單參數包含任何 不允許使用的字元。 邊緣公有雲和私有雲使用者
常見的診斷步驟
請使用下列其中一項工具/技巧診斷這個錯誤:
API Monitoring
如何使用 API Monitoring 診斷錯誤:
- 以使用者身分登入 Apigee Edge UI 適當角色。
切換到您要調查問題的機構。
- 前往「Analyze」(分析) >「API 監控 >調查頁面。
- 請選取您發現錯誤的確切時間範圍。
根據「時間」繪製「Fault Code」指標。
選取含有錯誤程式碼
protocol.http.BadFormData
的儲存格 如下所示:(查看較大的圖片)。
錯誤代碼
protocol.http.BadFormData
的相關資訊如下: 如下所示:(查看較大的圖片)。
按一下「查看記錄」,然後展開失敗要求的資料列。
- 在「Logs」(記錄檔) 視窗中,記下下列詳細資料:
- 狀態碼:
500
- 錯誤來源:
proxy
- 錯誤代碼:
protocol.http.BadFormData
- 錯誤政策:
extractvariables/EV-ExtractFormParams
- 狀態碼:
- 如果「Fault Source」為
proxy
,則「Fault Code」是protocol.http.BadFormData
和「Fault Policy」欄位並非空白,那麼 表示錯誤發生在 Fault 中的特定政策 政策正在讀取或擷取表單資料 (表單參數),其中包含 不允許使用的字元。 - 在這個範例中,X-Apigee-fault-policy 為
extractvariables/EV- ExtractFormParams,
,代表名稱為 讀取或擷取表單時,EV-ExtractFormParams 失敗 參數。
追蹤工具
如何使用追蹤工具診斷錯誤:
- 啟用追蹤工作階段
和下列其中一項:
- 等待
500 Internal Server Error
錯誤發生,或 - 如果可以重現問題,請發出 API 呼叫以重現問題
500 Internal Server Error
- 等待
確保已啟用「Show all FlowInfos」:
- 請選取其中一個失敗的要求,然後檢查追蹤記錄。
- 瀏覽追蹤記錄的各個階段,找出失敗之處 發生。
您通常會在下列任一政策中發現錯誤,如下所示:
在上述追蹤記錄範例中,請注意 名為
EV-ExtractFormParams
的 ExtractVariables 政策。找到失敗的特定政策後,前往名為「Error」的流程:
- 請留意追蹤記錄中的下列值:
錯誤:
Bad Form Data
州/省:
PROXY_REQ_FLOW
error.class:
com.apigee.rest.framework.BadRequestException
- 錯誤
Bad Form Data
值表示表單 參數中包含不允許使用的字元。 - 狀態的值
PROXY_REQ_FLOW,
表示 API Proxy 要求流程發生錯誤。
- 錯誤
- 前往追蹤記錄中的「AX」AX(已記錄 Analytics 資料) 階段,然後按一下 基礎架構
向下捲動至「Phase Details」-「Error Headers」部分 確定 X-Apigee-fault-code、X-Apigee-fault-source 的值。 和 X-Apigee-fault-policy,如下所示:
請注意,X-Apigee-fault-code 和 X-Apigee-fault-source 的值為 分別為
protocol.http.BadFormData
和policy
和 X-Apigee-fault-policy 並未空白。這表示 發生在 X-Apigee-fault-policy 中, 讀取或擷取表單資料 (表單參數),其中包含任何 禁止使用回應標頭 值 X-Apigee-fault-code protocol.http.BadFormData
X-Apigee-fault-source policy
X-Apigee-fault-policy extractvariables/EV-ExtractFormParams
- 在這個範例中,X-Apigee-fault-policy 為
extractvariables/EV- ExtractFormParams,
,代表名稱為EV-ExtractFormParams
無法讀取或擷取表單 參數。
NGINX
如何使用 NGINX 存取記錄診斷錯誤:
- 如果您是 Private Cloud 使用者,可以使用 NGINX 存取記錄
然後判斷 HTTP
500 Internal Server Error
的重要資訊。 查看 NGINX 存取記錄:
/opt/apigee/var/log/edge-router/nginx/ORG~ENV.PORT#_access_log
- 搜尋是否有任何
500
錯誤和錯誤代碼 在特定期間內的protocol.http.BadFormData
(如果發生問題的話) ) 或是發生任何請求失敗500
。 如果發現任何含有 X-Apigee-fault-code 的
500
錯誤 與protocol.http.BadFormData
的值相符,然後 確定 X-Apigee-fault-source 的價值 X-Apigee-fault-policy.NGINX 存取記錄中的 500 錯誤示例:
上述 NGINX 存取記錄的範例項目如下 X-Apigee-fault-code 和 X-Apigee-fault-source:
標頭 值 X-Apigee-fault-code protocol.http.BadFormData
X-Apigee-fault-source policy
X-Apigee-fault-policy extractvariables/EV-ExtractFormParams
- 請注意,X-Apigee-fault-code、X-Apigee-fault-source 的值
protocol.http.BadFormData
policy
和 X-Apigee-fault-policy 並未空白。這表示 出現於 X-Apigee-fault-policy, 中特定政策時, 讀取或擷取表單資料 (表單參數),其中包含任何 禁止使用 - 在這個範例中,X-Apigee-fault-policy 為
extractvariables/EV- ExtractFormParams,
,代表名稱為EV-ExtractFormParams
無法讀取表單 參數。
原因:要求中的表單參數含有不允許使用的字元
診斷
- 使用 API 監控、追蹤工具或 NGINX 存取記錄,判斷
500 Internal Server Error
的「錯誤程式碼」、「錯誤來源」和「錯誤政策」。 「常見診斷步驟」一節。 - 如果「Fault Code」為
protocol.http.BadFormData
,則「Fault Source」為 值proxy
或policy
,以及 Fault Policy 為非 ,空白,則代表「錯誤政策」,中指定的政策無法在 讀取或擷取表單資料 (表單參數)。 - 詳閱「錯誤政策」一節中所述的政策,並確認下列事項:
每個 ACL 都由一或多個項目組成
而這些項目包含兩項資訊
- 來源:判斷政策正在讀取還是擷取資料 要求或回應
- 表單參數:決定要在
政策。
範例 #1
示例 1:擷取表單參數的 ExtractVariables 政策:
<ExtractVariables name="EV-ExtractFormParms"> <DisplayName>EV-ExtractFormParams</DisplayName> <Source>request</Source> <FormParam name="username"> <Pattern ignoreCase="false">{username}</Pattern> </FormParam> <FormParam name="password"> <Pattern ignoreCase="false">{password}</Pattern> </FormParam> <VariablePrefix>forminfo</VariablePrefix> <IgnoreUnresolvedVariables>false</IgnoreUnresolvedVariables> </ExtractVariables>
在上述 ExtractVariables 政策中:
資料來源:
request
這項指令是由
<Source>
元素表示表單參數:
username
和password
這項機制是由
<Pattern>
元素中的<FormParam>
個元素
這表示表單參數
username
和/或password
做為 HTTP 要求的一部分,由用戶端傳遞至 Apigee Edge 含有禁止使用的字元。範例 #2
示例 #2:AssignMessage 政策複製表單參數:
<AssignMessage continueOnError="false" enabled="true" name="AM-CopyFormParams"> <Copy source="request"> <FormParams> <FormParam name="username"/> <FormParam name="password"/> </FormParams> </Copy> <AssignTo createNew="true" transport="http" type="request"/> </AssignMessage>
在上述 ExtractVariables 政策中:
來源:
request
這項指令會由
source
屬性中的<Copy>
個元素表單參數:
username
和password
這項指令會由
name
屬性中的<FormParam>
個元素
這表示表單參數為
username
、password
或 並透過用戶端傳送至 Apigee Edge 的 HTTP 要求,其中包含 所不允許使用的字元。
檢查是否有「不允許」的字元 步驟 3 中找到的表單參數中使用的字元 類型:
追蹤工具
如何使用追蹤工具進行驗證:
實際要求
如要使用實際要求進行驗證,請按照下列步驟操作:
- 如果您無法存取對目標伺服器發出的實際要求, 前往「解析度」。
- 如果您可以存取實際向 Apigee Edge 提出的要求,
步驟如下:
- 檢查表單資料內容,看看其中是否包含任何
不允許使用,例如百分比符號 (
%
) 或百分比符號 (%
) 後面跟著無效 十六進位字元。範例 #1
要求範例 #1:要求中包含表單資料
curl -X GET "https://HOSTALIAS/myproxy -H "Content-Type: application/x-www-form-urlencoded" -d "client_id=123456abc123&client_secret=c23578%ZY"
在此範例中,請注意
client_secret
元素 包含百分比符號 (%
),後面接著 十六進位字元ZY
無效。範例 #2
要求範例 2:透過檔案傳送的表單資料:
curl -X GET "https://HOSTALIAS/myproxy -H "Content-Type: application/x-www-form-urlencoded" -d @form_data.xml
form_data.xml 的內容:
xml=<user><username>abc1234@google.com</username><password>qwerty12345!@#$%</password></user>
在此範例中,請注意,元素
password
包含百分比符號 (%
),但該元素不應 以原始格式傳遞到表單資料中
- 檢查表單資料內容,看看其中是否包含任何
不允許使用,例如百分比符號 (
- 在以上兩個範例中,表單資料是透過 HTTP 要求的一部分傳送至 Apigee Edge 含有禁止使用的字元。
- 因此,Apigee Edge 會以
500 Internal Server Error
回應 並傳回錯誤代碼protocol.http.BadFormData
解析度
- 確認表單資料或參數形式的鍵和值中的所有特殊字元 做為 HTTP 要求的一部分,則一律會予以編碼,如 表單資料 - application/x-www-form-urlencoded。
- 對於上述範例,您可以按照下列方式修正問題:
範例 #1
範例 1:在要求中傳遞的表單資料:
請使用有效的 用於比對特定字元的 ASCII 字元的十六進位字元。 舉例來說,如要傳送錢幣符號 (
$
),請使用%24
如下所示:curl -X GET "https://HOSTALIAS/myproxy -H "Content-Type: application/x-www-form-urlencoded" -d "client_id=123456abc123&client_secret=c23578%24"
範例 #2
要求範例 2:透過檔案傳送的表單資料:
curl -X GET "https://HOSTALIAS/myproxy -H "Content-Type: application/x-www-form-urlencoded" -d @form_data.xml
form_data.xml 的內容:
使用 百分比編碼以百分比 (
%
) 符號表示,並將檔案修改為 包含%25
,如下所示:xml=<user><username>abc1234@google.com</username><password>qwerty12345!!@#$%25</password></user>
規格
Apigee Edge 預期會根據下列規格傳送表單資料:
規格 |
---|
表單資料 - application/x-www-form-urlencoded |
如果您仍需 Apigee 支援團隊的協助,請前往「必須收集 診斷資訊。
必須收集診斷資訊
如果按照上述說明操作後仍無法解決問題,請收集下列資訊 ,然後與 Apigee Edge 支援團隊聯絡:
如果您是公有雲使用者,請提供下列資訊:
- 機構名稱
- 環境名稱
- API Proxy 名稱
- 完成
curl
指令,用來重現 傳回500 Internal Server Error
以及錯誤代碼protocol.http.BadFormData
- API 要求的追蹤檔
如果您是 Private Cloud 使用者,請提供下列資訊:
- 偵測到失敗要求的完整錯誤訊息
- 環境名稱
- API Proxy 組合
- API 要求的追蹤檔
NGINX 存取記錄
/opt/apigee/var/log/edge-router/nginx/ORG~ENV.PORT#_access_log
其中: ORG、ENV 和 PORT# 會替換為 實際價值
訊息處理器系統記錄
/opt/apigee/var/log/edge-message-processor/logs/system.log