我花了一整天想弄清楚我的 Flask API 伺服器在瀏覽器中回傳亂碼的原因。有趣的是,我其他的端點都運作正常,唯獨我剛新增的這條路由有問題。以下是我從中學到、用來修復這個問題的方法。
找出問題的原因
我了解到造成這個問題主要有三個原因。
- Content-Type - charset 沒有設為 UTF-8,或者甚至沒有被辨識為 JSON
- Content-Encoding - 瀏覽器對 JSON 的預設自動壓縮與 API 的編碼方式發生衝突。
兩種檢查方式
cURL
開啟你的終端機並使用 cURL
curl -v "https://yourdomain.com/endpoint?"如果 JSON 能正確顯示,代表問題最可能出在瀏覽器。
如果顯示的是亂碼,請確認你在 Flask 應用程式中有將 charset 設為 UTF-8。因為這代表問題不在於傳輸,而是根本沒有在 Flask 內正確處理,可能是物件型別或編碼的問題。
瀏覽器中的開發者工具
- 前往 Network 分頁並重新整理你的端點頁面
- 檢查 Content-Type 是否為 ‘application/json; charset=UTF-8’
解決方案
Content-Type
如果缺少 application/json 或 charset=UTF-8,請為你的端點在 Flask API 應用程式中加入以下 response.header:
response.headers['Content-Type'] = 'application/json; charset=UTF-8'現在,重新啟動應用程式並再試一次,看看是否有效。如果沒效,請繼續進行下一步。
Content-Encoding
現在,你已確認 Content-Type 不是問題所在,因為它正確顯示為 application/json; charset=UTF-8。讓我們繼續探討第二個原因——編碼錯誤。
預設情況下,當 Flask API 將回應傳送給瀏覽器時,會自動壓縮內容。接著,瀏覽器會嘗試解碼。然而,基於某些原因,它無法正確解碼。
最完美的例子就是 cURL -v 能取得正確的回應,但在瀏覽器中卻是亂碼。(這就是我的情況。)cURL 預設不會接收壓縮/編碼過的回應,這就是為什麼它在 cURL 中正常,但在瀏覽器中卻不行。
要修復這個問題,你必須在 Flask API 應用程式的回應中加入以下內容:
response.headers['Content-Encoding'] = 'identity'這會預設停用壓縮,讓你的瀏覽器能取得與 cURL 相同的內容。
這樣應該就能修復了。
祝你好運。