小编典典

Flask开发服务器中静态文件的URL路由冲突

python

我想定义一个包含三个变量组件的url规则,例如:

@app.route('/<var_1>/<var_2>/<var3>/')

但是我发现开发服务器在尝试匹配静态文件之前会评估这些规则。所以像这样:

/static/images/img.jpg

会被我的url规则捕获,而不是转发给内置的静态文件处理程序。有没有一种方法可以强制开发服务器首先匹配静态文件?

PS仅当规则具有两个以上可变组成部分时,这才是问题。


阅读 209

收藏
2020-12-20

共1个答案

小编典典

这是werkzeug路线优化功能。见Map.addMap.update并且Rule.match_compare_key

def match_compare_key(self):
    """The match compare key for sorting.

    Current implementation:

    1. rules without any arguments come first for performance
    reasons only as we expect them to match faster and some
    common ones usually don't have any arguments (index pages etc.)
    2. The more complex rules come first so the second argument is the
    negative length of the number of weights.
    3. lastly we order by the actual weights.

    :internal:
    """
    return bool(self.arguments), -len(self._weights), self._weights

self.arguments-当前参数self._weights-路径深度。

因为'/<var_1>/<var_2>/<var3>/'我们有(True, -3, [(1, 100), (1, 100), (1, 100)])。有(1, 100)-最大长度为100的默认字符串参数。

因为'/static/<path:filename>'我们有(True, -2, [(0, -6), (1, 200)])。有(0, 1)-路径非参数字符串长度static(1, 200)-路径字符串参数最大长度200。

因此,我找不到任何精美的方法来设置自己的Map实现Flask.url_map或为地图规则设置优先级。解决方案:

  1. Flask应用程序设置为app = Flask(static_path='static', static_url_path='/more/then/your/max/variables/path/depth/static')
  2. 更改@app.route('/<var_1>/<var_2>/<var3>/')@app.route('/prefix/<var_1>/<var_2>/<var3>/')
  3. 添加自己的转换器并用作@app.route('/<no_static:var_1>/<var_2>/<var3>/')
  4. 导入werkzeug.routing,创建自己的地图实现,更改werkzeug.routing.Map为自己的实现,导入flask
  5. 在生产环境中使用服务器。
2020-12-20