首页 > 解决方案 > 如何解决由 CGIRootFix 引起的 404 错误?

问题描述

我将 Flask 部署在需要使用 CGI 服务的共享服务器上。我已经能够使用以下 .htaccess 代码从 URL 中删除文件名:

AddHandler cgi-script .cgi .pl

RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ /home/tetra/public_html/cgi-bin/tetra.cgi/$1 [L]

但是,每当我使用 url_for() 生成链接时,它都会将 cgi-bin 文件路径插入回链接中,因此,https://servername/auth/login变为https://servername/cgi-bin/app.cgi/auth/login.

当我cgi-bin/app.cgi/从 URL 中删除时,URL 工作正常。在搜索此问题时,我发现 CGIRootFix 可能用于通过从 URL 中删除文件路径来解决此问题:

http://werkzeug.pocoo.org/docs/0.14/contrib/fixers/

我尝试将此添加到我的 CGI 文件中:

from werkzeug.contrib.fixers import CGIRootFix

app = CGIRootFix(app,app_root='/')

完整文件:

#!<path redacted>

#path to python packages
import sys
sys.path.insert(0, '<path redacted>')

from wsgiref.handlers import CGIHandler
from myapp import app
from werkzeug.contrib.fixers import CGIRootFix

app = CGIRootFix(app,app_root='/')

if __name__ == '__main__':
  CGIHandler().run(app)

这确实解决了生成的 URL 帽子 url_for() 的问题,我可以通过命令行从烧瓶外壳进行测试:

>>> from flask import url_for
>>> url_for('main.index')
'http://servername/'
>>> url_for('auth.login')
'http://servername/auth/login'

但是...现在访问 URL 会导致 404 错误。没有任何页面使用任何 URL 加载,无论是所需的 URL 还是包含文件名的 URL。这一定是一些愚蠢的配置问题,但文档有点薄,就像我在这个问题上发现的其他问题一样。

我也尝试过app.wsgi_app = CGIRootFix(app.wsgi_app,app_root='/')和我之前看到的线程的一些其他变体。

知道当我使用 CGIRootFix 时是什么导致它变为 404 以及我能做些什么来让它加载具有所需 URL 的页面吗?

标签: python-3.xflaskcgi

解决方案


我从来没有想过如何让这个修复程序工作,但是,我相信这可能是因为它是一个过时的解决方案。我能够通过代码中的以下更改来修复链接:

添加app.config['_external']=True到配置中,然后在 .cgi 文件中添加os.environ['SCRIPT_NAME']=""到应用程序执行行之前。您也可以SCRIPT_NAME=""为您的站点添加配置,并且仅在还设置了 _external 时才有效。最终结果是它不起作用,我的 URL 是正确的。

真的希望这可以帮助处于相同情况的其他人。


推荐阅读