我有一个Flask应用,我需要向其中传递几个包含斜杠的参数。例如,我有parameter1 = "Clothes/Bottoms"
和parameter2 = "Pants/Jeans"
。我尝试过这种方式:
在我的HTML / JS中:
par1 = encodeURIComponent(parameter1);
par2 = encodeURIComponent(parameter2);
console.log("Par1 = ",par1," par2 = ",par2);
$.ajax({
type:'post',
url:'/get_data'+'/'+par1+'/'+par2,
....
});
以及在我的app.py
中:
@app.route('/get_data/<path:par1>/<path:par2>/',methods=['GET','POST'])
def get_data(par1, par2):
print("In get_data with par1 ",par1," and par2 ",par2)
....
我从Javascript打印输出中看到,两个参数在编码后看起来都不错,但是Python打印输出是:
In get_data with par1 Clothes and par2 Bottoms/Pants/Jeans
因此,它以某种方式将par1
的{{1}}中的斜杠误认为是部分URL,并将"Clothes/Bottoms"
转换为"Bottoms"
。
是否有比仅添加par2
更好的用斜杠处理多个参数的方法?
答案 0 :(得分:1)
对于/get_data/<path:par1>/<path:par2>/
,Flask无法在收到诸如/get_data/Clothes/Bottoms/Pants/Jeans/
之类的请求时“知道”哪个斜杠是分隔符。
如果par1
中的斜杠数目是固定的,则可以将路径作为单个参数接收,然后将其分为两个:
@app.route('/get_data/<path:pars>/')
def get_data(pars):
par1 = '/'.join(pars.split("/",2)[:2]) #par1 is everything up until the 2nd slash
par2 = pars.split("/",2)[2:][0] #par2 is everything after the second slash
否则,您可以简单地将分隔斜杠替换为另一个字符,例如:
@app.route('/get_data/<path:par1>-<path:par2>/')
答案 1 :(得分:1)
了解烧瓶(werkzeug)的布线。暂时不用您在JavaScript中使用的编码。
werkzeug的path
转换器使用的正则表达式模式为[^/].*?
。这样可以在网址路径中使用任意数量的/
。这意味着只有part1 get_data/<path:par1>
可以同时接受get_data/Clothes/Bottoms
或get_data/Clothes/Bottoms/Pants/Jeans
。
您在part1和par2中使用了两个path
转换器,这很不好,因为part1可以使用所有斜杠。
现在是另一个问题。为什么甚至在对网址进行编码后也无法按预期运行。
Flask使用Werkzeug默认的WSGI服务器。 WSGI库在将其用于路由之前未对uri进行转义。也就是说,get_data/Clothes%2FBottoms
在路由时会转换为get_data/Clothes/Bottoms
。
在您的情况下,路由器收到get_data/Clothes/Bottoms/Pants/Jeans
,此处将“衣服”作为第1部分,其余作为第2部分。
请参阅https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/recognize-expanded-volume-linux.html。
解决方案
在JavaScript中双重转义可能是此处的解决方法。
path
转换器也可以替换为string
。
par1 = encodeURIComponent(encodeURIComponent(parameter1));
par2 = encodeURIComponent(encodeURIComponent(parameter2));
$.ajax({
type:'post',
url:'http://localhost:8000/get_data'+'/'+par1+'/'+par2+'/'});
然后在flask应用程序中解码以获取您的字符串
from urllib import unquote_plus
@app.route('/get_data/<string:par1>/<string:par2>/',methods=['GET','POST'])
def get_data(par1, par2):
print unquote_plus(par1), unquote_plus(par1)