【问题标题】:Multiple 'path' parameters in flask route lead to incorrect parsing烧瓶路由中的多个“路径”参数导致解析不正确
【发布时间】:2021-10-08 10:24:08
【问题描述】:

问题描述

当使用烧瓶@app.route 时,应该可以一个接一个地发送三个path 参数,但是当涉及“/”时,烧瓶端的解析会错误地将它们分开.

小例子

Flask Server 使用这个路由,这里有三个'path'参数firstsecondthird

from flask import Flask, jsonify

app = Flask(__name__, static_folder='static')

@app.route('/pathtest/<path:first>/<path:second>/<path:third>/', methods=['GET'])
def pathTest(first, second, third):
    print("1: " + first, flush=True) 
    print("2: " + second, flush=True)
    print("3: " + third, flush=True) 
    return jsonify({ 'data': '%s' % True})

如果我们要发送三个参数,编码如下:

String Encoded
'hello?/this' hello%3F%2Fthis
'is/a' is%2Fa
'test!' test%21

我们调用的整个 url(我们的服务器在端口 8085 上)是

http://0.0.0.0:8085/pathtest/hello%3F%2Fthis/is%2Fa/test%21/.

结果:

预期

1: 'hello?/this'
2: 'is/a'
3: 'test!'

实际

1: 'hello?'
2: 'this'
3: 'is/a/test!'

'解决方案'

似乎可行的方法是将路线分开:

@app.route('/pathtest/first/<path:first>/second/<path:second>/third/<path:third>/', methods=['GET'])

我使用flask build in server进行测试,但也通过nginx尝试过。

问题

这种行为的解释是什么?这是一个错误还是我在 path 文档或我在客户端对字符串进行编码的方式中遗漏了什么?

祝你好运

答案

0.0.0.0:8085/pathtest/hello%3F%2Fthis/is%2Fa/test%21 将转换为 0.0.0.0:8085/pathtest/hello?/this/is/a/test!在 Flask 收到之前。

似乎并非如此;检查 request.url 的内置烧瓶服务器以及两者之间的 nginx 和 uWSGI 显示“预期”编码的 url 0.0.0.0:8085/pathtest/hello%3F%2Fthis/is%2Fa/test%21

【问题讨论】:

  • 当我使用urllib.parse.unquote('http://0.0.0.0:8085/pathtest/hello%3F%2Fthis/is%2Fa/test%21/') 然后我得到'http://0.0.0.0:8085/pathtest/hello?/this/is/a/test!/' 并且我不知道第一条路径的终点在哪里,第二条路径的终点在哪里 - 并且可能 Flask 有同样的问题。首先它可能会取消引用它,然后它在检测路径末端时遇到问题。您应该使用路径中没有的 char - 即。 |,;
  • 你是如何运行你的 Flask 应用程序的?你是使用内置服务器还是使用其他的(例如nginx)?
  • 如果您使用 from flask import request 并且在函数中使用 print(request.url) 然后您会看到 http://0.0.0.0:5000/pathtest/hello%3F/this/is/a/test%21/ 这是它尝试在三个路径上拆分的 url - 并且没有方法可以识别在哪里第一条和第二条路径的结束。
  • 在 Flask 处理之前将 %2F 转换为 / 似乎是 WSGI 或 Apache 的一个限制。有关更多信息和一些解决方法,请参阅github.com/pallets/flask/issues/900
  • @furas 从我从这里了解的flask.palletsprojects.com/en/2.0.x/quickstart 询问“路径”时,它应该'也接受斜杠[在字符串中]'

标签: python flask url path routes


【解决方案1】:

这种行为的解释是什么?

好像是先URL解码,然后是路径解析,所以

http://0.0.0.0:8085/pathtest/hello%3F%2Fthis/is%2Fa/test%21/

变成

http://0.0.0.0:8085/pathtest/hello?/this/is/a/test!/

然后是路径解析,因为%-decoding 早先完成,所以无法区分/%2F。我怀疑这可能取决于使用的服务器及其设置。由于依赖差异 /%2F 显然不可靠,我建议更改您的规范,以便使用其他字符(永远不会出现在路径内)用于剪切路径。

【讨论】:

  • 我不明白为什么这条路径 @app.route('/pathtest/first/&lt;path:first&gt;/second/&lt;path:second&gt;/third/&lt;path:third&gt;/', methods=['GET'])``` works everywhere though. I can see that relying on %2F` 不是很健壮 - 但是将 / 转换为 | 或类似的似乎是一场等待发生的事故。请注意,我想发送“通用”字符串,而不仅仅是显式路径。
猜你喜欢
  • 2021-10-28
  • 2021-03-22
  • 1970-01-01
  • 1970-01-01
  • 2018-07-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-05-20
相关资源
最近更新 更多