Flask API サーバーからブラウザに返されるレスポンスが文字化けする原因を突き止めるのに、丸一日費やしました。興味深いことに、他のエンドポイントは問題なく動作するのに、新しく追加したこのルートだけがうまくいきませんでした。この問題を解決するために学んだことを以下にまとめます。
原因を突き止める
この問題を引き起こす主な理由は3つあることがわかりました。
- Content-Type - charset が UTF-8 に設定されていない、またはそもそも JSON として認識されていない
- Content-Encoding - ブラウザの JSON に対するデフォルトの自動圧縮が、API のエンコード方式と競合している
確認する2つの方法
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 と正しく表示されています。では2つ目の原因であるエンコードエラーに進みましょう。
デフォルトでは、Flask API がブラウザにレスポンスを送信する際、コンテンツを自動的に圧縮します。そしてブラウザがそれをデコードしようとします。しかし、何らかの理由で正しくデコードできないことがあります。
完璧な例が cURL -v では正しいレスポンスが得られるのに、ブラウザでは文字化けするケースです(これが私のケースでした)。cURL はデフォルトで圧縮・エンコードされたレスポンスを受け取らないため、cURL では動作するのにブラウザでは動作しないのです。
修正するには、Flask API アプリのレスポンスに以下を追加する必要があります:
response.headers['Content-Encoding'] = 'identity'これによりデフォルトで圧縮が無効になり、ブラウザは cURL が受け取っているものと同じものを受け取れるようになります。
これで修正されるはずです。
幸運を祈ります。