#python #python_3x #utf_8 #windows_10 #flask
Дано: Windows 10, Python 3.4, PyScripter, Flask
Есть файл (допустим main.py) в котором вызывается шаблон
def index():
return render_template('index.html')
в index.html поле для ввода
Если так запустить localhost:5000 то все ок, но если изменить на русский язык
то выдает ошибку
builtins.UnicodeDecodeError
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xe0 in position 437: >invalid
continuation byte
Python3 по умолчанию использует кодировку utf-8, в файле html также
meta charset="utf-8" прописано.
Traceback начинает ругаться на строчку
return render_template('index.html') в main.py.
Ответы
Ответ 1
Недостаточно прописать , нужно ещё сам файл сохранить именно
в кодировке utf-8.
Зачем?
Прописанная мета никак не влияет на содержимое файла. Она лишь даёт подсказку браузеру,
какую кодировку использовать для декодирования файла. Можно написать мету cp1251, а
сохранить всё равно в utf-8 — это будет работать, только в браузере будут кракозябры,
потому что он послушается подсказку и попытается раскодировать utf-8 байты как cp1251
символы.
Flask не использует мету. Он (точнее, Jinja2) тупо читает текстовый файл и интерпретирует
его как шаблон Jinja2. А HTML ли там, или CSS, или JS, или JSON — фласку пофиг.
Шаблонизатор Jinja2 по умолчанию пытается прочитать файлы как utf-8, и ему плевать
на ваши меты.
Но это ещё не всё: вся обработка шаблона завязана на юникодных строках (у которых
для простоты можно считать, что они не имеют конкретной кодировки, так как это деталь
реализации питона, для нас не важная), и render_template возвращает юникодную (не байтовую!)
строку независимо от того, в какой кодировке был сохранён файл и что там понаписано
в метах.
Перед отправкой ответа браузера Flask должен обратно закодировать юникодную строку
в какие-то байты, и по умолчанию для этого используется кодировка utf-8.
Таким образом неважно, в какой кодировке сохранён файл и что написано в мете — браузеру
будут отправлены всегда utf-8 байты! Браузер будет пытаться раскодировать эти байты
согласно подсказке, прописанной в мете. То есть если вы замените кодировку по умолчанию
в Jinja2 (и при этом не замените в Flask Response), то кодировка исходного файла-шаблона
и кодировка, прописанная в мете, вообще не обязаны совпадать :)
Кодировки Python-файлов и кодировки по умолчанию в самом Python в данном конкретном
случае не играют никакой роли.
Комментариев нет:
Отправить комментарий