#python #url #flask #encoding #werkzeug
#python #url #flask #кодирование #werkzeug
Вопрос:
ПРАВКА2: Прошу прощения за отсутствие ясности. Я приведу несколько значений. Первый — это URL-адрес, который я вызываю с помощью моего интерфейсного приложения. Второе значение — это значение перед вызовом urllib.unquote
. Третье — это значение после вызова urlib.unquote
.
интерфейс:
console.log('http://localhost:8080/v1/' encodeURIComponent(name))
серверная часть:
def f(param=''):
print('*', param)
param = urllib.unquote(param)
print('**', param)
Пример.
http://localhost:8080/v1/https://google.com
* https://google.com
** https://google.com
Пример 2.
http://localhost:8080/v1/foo%20bar
* foo bar
** foo bar
Пример 3.
http://localhost:8080/v1/foo bar
* foo bar
** foo bar
Спасибо, что проявили терпение и помогли мне с этим. Я приношу извинения за неясность в моем первоначальном сообщении.
РЕДАКТИРОВАТЬ: Короче говоря, если я вызываю /v1/%20
, param равен " "
в конце функции, вместо " "
того, чтобы в начале функции он был равен " "
, а не "%20"
.
В настоящее время я работаю над приложением Flask, используя Python 2.7.
Я пытаюсь создать функцию, которая может обрабатывать параметры URL.
@app.route('/v1/<param>', methods=['DELETE'])
def f(param=''):
param = urllib.unquote(param)
В моем интерфейсном приложении я вызываю эту функцию, кодируя param
. Однако, если я передаю "foo bar"
и "foo bar"
функции, param
значение преобразуется в то же самое значение — "foo bar"
, когда действительно "foo bar"
должно быть "foo bar"
и "foo bar"
должно быть "foo bar"
.
Из-за этой ошибки я не могу удалить "foo bar"
запись. Если я попытаюсь удалить его, он будет удален "foo bar"
, и как только "foo bar"
будет удален, "foo bar"
запись никогда не будет удалена.
Я полагаю, это потому, что " "
не равно "%20"
, хотя это и есть параметр. Когда я печатаю это значение перед вызовом, urllib.unquote(param)
оно уже равно " "
. Затем, когда я вызываю, urllib.unquote(param)
значение изменяется на " "
.
Я не совсем уверен, что это ошибка в Flask / Werkzeug, но это приводит к тому, что мое приложение не работает.
Есть ли у вас какие-либо предложения по устранению этой проблемы? Спасибо!
Комментарии:
1.Нет,
foo bar
естьfoo bar
. Дажеfoo bar
в строке URL-адреса браузера фактически отправляется на сервер какfoo bar
. Если вы действительно хотелиfoo bar
после декодирования URL, то отправьтеfoo%20bar
.2. Извините. Должно быть, я был неясен.
"foo%20bar"
равно"foo bar"
ПЕРЕД изменением значения с помощьюurllib.unquote
. Поэтому, если я вызываю/v1/foo%20bar
, значение параметра равно"foo bar"
вместо"foo bar"
@MartijnPieters3. Так почему же вы тогда вообще используете
urllib.unquote()
?4. @MartijnPieters Я буду передавать URL-адреса в параметр.
Ответ №1:
Нет, Flask обычно совершенно правильно обрабатывает процентное кодирование. Параметры в URL-адресе кодируются в процентах, и они расшифровываются для вас при настройке среды WSGI. Затем Flask передает это вашему маршруту при сопоставлении.
Вам не нужно снова декодировать значение параметра, удалите свой urllib.unquote()
вызов.
Ваш браузер фактически закодирует пробелы в URL-адресе на
для вас, даже если в строке местоположения будет отображаться пробел. Строка местоположения декодирует компоненты в процентном кодировании, чтобы сделать возможным чтение международных символов (например, так どうもありがとう
показано как どうもありがとう
).
Если у вас возникли проблемы с кодированными косыми чертами ( /
, /
), см. Выпуск # 900, следует рассмотреть крайние случаи с директивами Apache (и другими серверами WSGI). Вам нужно будет использовать <path:param>
компонент для сопоставления с ними, потому что тип параметра по умолчанию string
не будет соответствовать косым чертам.
Если я использую следующий тестовый скрипт с именем routetest.py
:
from flask import Flask
try:
from urllib.parse import unquote # PY3
except ImportError:
from urllib import unquote # PY2
app = Flask(__name__)
@app.route('/v1/<path:param>') # NOTE: <path:param> is required to match /
def f(param=''):
return (
f"param: {param}ndecoded param: {unquote(param)}n",
200,
{'content-type': 'text/plain'}
)
используйте FLASK_APP=routetest flask run
для запуска этого скрипта localhost:5000
, тогда я не смогу воспроизвести ваши проблемы:
$ curl http://localhost:5000/v1/https://google.com
param: https://google.com
decoded param: https://google.com
$ curl http://localhost:5000/v1/foo%20bar
param: foo bar
decoded param: foo bar
$ curl http://localhost:5000/v1/foo bar
param: foo bar
decoded param: foo bar
это может означать только то, что у вас есть сервер WSGI, который неправильно обрабатывает кавычки в путях.
Ответ №2:
Я думаю, проблема в том, что вы не понимаете кодировку URL 🙂 Требуется избегать пробелов, поэтому браузер переводит их в и автоматически возвращает обратно с помощью flask. Прочитайте это для получения дополнительной информации: https://www.w3schools.com/tags/ref_urlencode.asp
Решение: отправьте закодированное foo bar
на сервер с foo%20bar
.
Комментарии:
1. Извините, я был неясен. Я обновил свой вопрос. Для удобства ОТРЕДАКТИРУЙТЕ: Короче говоря, если я вызываю /v1 /%20, параметр равен » » в конце функции вместо » »
2. Интересно, есть ли какие-либо изменения в Flask в последнее время? Мое приложение Flask недавно сломалось, потому что оно не автоматически декодируется
в пробел, мне нужно использовать
urllib.unquote
сейчас.