查看 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_FLOWerror.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.BadFormDataX-Apigee-fault-source policyX-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.BadFormDataX-Apigee-fault-source policyX-Apigee-fault-policy extractvariables/EV-ExtractFormParams- 請注意,X-Apigee-fault-code、X-Apigee-fault-source 的值
protocol.http.BadFormDatapolicy和 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