当サイトは、アフィリエイト広告を利用しています
flaskで作ったREST APIのレスポンスの日本語が文字化けしたので
対応を方法を忘備録として残しておく。
※Flask==3.0.2で発生した
下記のような文字化けが発生する
$ curl -X GET http://localhost:5000/[{"book": "\u3059\u3079\u3066\u304cF\u306b\u306a\u308b","id": "1","name": "\u68ee\u535a\u55e3"},{"book": "\u6697\u95c7\u5742\u306e\u4eba\u98df\u3044\u306e\u6728","id": "2","name": "\u5cf6\u7530\u8358\u53f8"},{"book": "\u540d\u524d\u63a2\u3057\u306e\u653e\u8ab2\u5f8c","id": "3","name": "\u8fbb\u6751\u6df1\u6708"},{"book": "\u9b4d\u9b4e\u306e\u5323","id": "4","name": "\u4eac\u6975\u590f\u5f66"}]
レスポンスの日本語が文字化けした状況をまとめる。
下記のようなFlaskのREST APIを実装、起動した
.|-- app|-- __init__.py|-- api.py`-- wsgi.py
シンプルなREST API
from flask import Flask, jsonify,make_response# ディクショナリusers = [{"id": "1", "name": "森博嗣", "book":"すべてがFになる"},{"id": "2", "name": "島田荘司", "book":"暗闇坂の人食いの木"},{"id": "3", "name": "辻村深月", "book":"名前探しの放課後"},{"id": "4", "name": "京極夏彦", "book":"魍魎の匣"}]def routers(api):@api.route('/', methods=['GET'])def get_users():return make_response(jsonify(users), 200)# flaskインスタンス作成def create_app():# 作成api = Flask(__name__)# 関数ベースのルーティング設定routers(api)return api
GETリクエストでusersをレスポンスとして返却する
# flaskインスタンス生成関数をimportfrom app.api import create_app# flaskインスタンスを生成api = create_app()
Flaskアプリケーションをで起動するためのエントリーポイント
FlaskのREST APIについては下記で詳しくまとめています。
発生する際、リクエストをどう送ったかをまとめる。
下記のツール等でリクエストを送信し検証した
先に結論をいうと3,4などのツールを使った場合は文字化けは発生しない。
ツール系はそのへんちゃんとしてくれているらしい。
文字化けする
$ curl -X GET http://localhost:5000/[{"book": "\u3059\u3079\u3066\u304cF\u306b\u306a\u308b","id": "1","name": "\u68ee\u535a\u55e3"},{"book": "\u6697\u95c7\u5742\u306e\u4eba\u98df\u3044\u306e\u6728","id": "2","name": "\u5cf6\u7530\u8358\u53f8"},{"book": "\u540d\u524d\u63a2\u3057\u306e\u653e\u8ab2\u5f8c","id": "3","name": "\u8fbb\u6751\u6df1\u6708"},{"book": "\u9b4d\u9b4e\u306e\u5323","id": "4","name": "\u4eac\u6975\u590f\u5f66"}]
冒頭の通り、文字化けする
文字化けしない
デフォルトでは、FlaskはJSONレスポンスを生成する際に、ASCIIモードでエンコードするため
非ASCII文字である日本語もASCIIモードで出力され文字化けする
非ASCII文字をUnicodeエスケープ(\uXXXX)形式で出力せず、そのままのUTF-8形式で出力するようにする。 これにより日本語などの非ASCII文字がエスケープされず、そのままJSONレスポンスに含まれるようになる。
具体的いは下記のようにする
from flask import Flask, jsonify,make_response# ディクショナリusers = [{"id": "1", "name": "森博嗣", "book":"すべてがFになる"},{"id": "2", "name": "島田荘司", "book":"暗闇坂の人食いの木"},{"id": "3", "name": "辻村深月", "book":"名前探しの放課後"},{"id": "4", "name": "京極夏彦", "book":"魍魎の匣"}]def routers(api):@api.route('/', methods=['GET'])def get_users():return make_response(jsonify(users), 200)# flaskインスタンス作成def create_app():# 作成api = Flask(__name__)# 日本語文字化け対応api.json.ensure_ascii = False# 関数ベースのルーティング設定routers(api)return api
これでブラウザでもcurlコマンドでも文字化けしなくなる。
ネットを調べると
api.json.ensure_ascii = False
ではなく
api.config['JSON_AS_ASCII'] = False
にするという対応をよく見るが、今回動作させた
Flask==3.0.2では
api.config['JSON_AS_ASCII'] = False
では文字化けは解消されなかった。
※古いversionでは有効かもしれない
flaskのレスポンス文字化けについてすこし調べてみた。
curlやブラウザから実行した時のみ発生したので
気を付けようと思った。
※実際の開発ではツールを使うことが多いので。。。