编辑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%3A%2F%2Fgoogle.com
* https:%2F%2Fgoogle.com
** https://google.com
EX2。
http://localhost:8080/v1/foo%2520bar
* foo%20bar
** foo bar
EX3。
http://localhost:8080/v1/foo%20bar
* foo bar
** foo bar
感谢您的耐心和帮助我。我为在原帖中不清楚而道歉。
编辑:简而言之,如果我调用/v1/%2520
,param在函数末尾等于" "
,而不是"%20"
,在函数的开头它等于"%20"
而不是"%2520"
。
我目前正在使用Python 2.7开发Flask应用程序。
我正在尝试创建一个可以处理URL参数的函数。
@app.route('/v1/<param>', methods=['DELETE'])
def f(param=''):
param = urllib.unquote(param)
在我的前端应用程序中,我通过编码param
来调用此函数。然而,如果我将"foo bar"
和"foo%20bar"
传递给函数,param
被解析为相同的值 - "foo bar"
,当真正的"foo bar"
应该是"foo bar"
和"foo%20bar"
应该是"foo%20bar"
。
由于这个错误,我无法删除"foo%20bar"
条目。如果我尝试删除它,它将删除"foo bar"
,并且一旦"foo bar"
被删除,"foo%20bar"
entry将永远不会被删除。
我相信这是因为"%20"
不等于"%2520"
,即使这就是param是什么。当我在调用urllib.unquote(param)
之前打印此值时,它已经等于"%20"
。然后,当我调用urllib.unquote(param)
时,值变为" "
。
我不确定这是否是Flask / Werkzeug中的错误,但它导致我的应用程序无法正常工作。
你对修复这个问题有什么建议吗?谢谢!
不,Flask通常处理完全正确的编码百分比。 URL中的参数是百分比编码,并在设置WSGI环境时为您解码。然后Flask在匹配时将其传递到您的路线。
您不需要再次解码参数值,删除您的urllib.unquote()
调用。
您的浏览器实际上会为您的%20
编码URL中的空格,即使位置栏会显示空格。位置栏解码百分比编码的组件,以便可以读取国际字符(例如,%E3%81%A9%E3%81%86%E3%82%82%E3%81%82%E3%82%8A%E3%81%8C%E3%81%A8%E3%81%86
显示为どうもありがとう
)。
如果你遇到编码斜杠(/
,%2F
)的问题,那么请参阅issue #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: {urllib.parse.unquote(param)}\n",
200,
{'content-type': 'text/plain'}
)
使用FLASK_APP=routetest flask run
在localhost:5000
上启动此脚本,然后我无法重现您的问题:
$ curl http://localhost:5000/v1/https%3A%2F%2Fgoogle.com
param: https://google.com
decoded param: https://google.com
$ curl http://localhost:5000/v1/foo%2520bar
param: foo%20bar
decoded param: foo bar
$ curl http://localhost:5000/v1/foo%20bar
param: foo bar
decoded param: foo bar
这只能意味着你有一个错误处理路径引用的WSGI服务器。
我认为问题是你不理解URL编码:)它需要避免空格,所以它们被浏览器翻译为%20并由烧瓶自动返回。阅读本文以获取更多信息:https://www.w3schools.com/tags/ref_urlencode.asp
解决方案:使用foo%20bar
将编码的foo%2520bar
发送到服务器。