如何解决由 CGIRootFix 引起的 404 错误?
How can I resolve 404 errors caused by CGIRootFix?
我正在共享服务器上部署 Flask,我需要用 CGI 为它提供服务。我已经能够使用以下 .htaccess 代码从 URL 中删除文件名:
AddHandler cgi-script .cgi .pl
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ /home/tetra/public_html/cgi-bin/tetra.cgi/ [L]
但是,任何时候我使用 url_for() 生成 link,它都会将 cgi-bin 文件路径插入回 link,因此,https://servername/auth/login
变成 https://servername/cgi-bin/app.cgi/auth/login
.
当我从 URL 中删除 cgi-bin/app.cgi/
时,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)
这确实解决了 URLs 帽子 url_for() 生成的问题,我可以通过命令行从 flask shell 进行测试:
>>> from flask import url_for
>>> url_for('main.index')
'http://servername/'
>>> url_for('auth.login')
'http://servername/auth/login'
但是...访问 URL 现在会导致 404 错误。 None 的页面使用任何 URL 加载,可以是所需的 URL 或包含文件名的 URL。这一定是一些愚蠢的配置问题,但文档有点薄,我在这个问题上发现的其他问题也是如此。
我还尝试了 app.wsgi_app = CGIRootFix(app.wsgi_app,app_root='/')
以及我之前看到的线程的一些其他变体。
知道是什么导致我使用 CGIRootFix 时出现 404 吗?我可以做些什么来让它加载所需的 URL 页面?
我从来不知道如何让这个修复程序工作,但是,我相信这可能是因为它是一个过时的解决方案。我能够通过我的代码中的以下更改修复链接:
将 app.config['_external']=True
添加到配置中,然后在 .cgi 文件中,在应用程序执行行之前添加 os.environ['SCRIPT_NAME']=""
。您也可以将 SCRIPT_NAME=""
添加到您站点的配置中,并且只有在同时设置了 _external 时才有效。最终结果是它不起作用,我的 URL 是正确的。
真心希望这对处于相同情况的其他人有所帮助。
我正在共享服务器上部署 Flask,我需要用 CGI 为它提供服务。我已经能够使用以下 .htaccess 代码从 URL 中删除文件名:
AddHandler cgi-script .cgi .pl
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ /home/tetra/public_html/cgi-bin/tetra.cgi/ [L]
但是,任何时候我使用 url_for() 生成 link,它都会将 cgi-bin 文件路径插入回 link,因此,https://servername/auth/login
变成 https://servername/cgi-bin/app.cgi/auth/login
.
当我从 URL 中删除 cgi-bin/app.cgi/
时,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)
这确实解决了 URLs 帽子 url_for() 生成的问题,我可以通过命令行从 flask shell 进行测试:
>>> from flask import url_for
>>> url_for('main.index')
'http://servername/'
>>> url_for('auth.login')
'http://servername/auth/login'
但是...访问 URL 现在会导致 404 错误。 None 的页面使用任何 URL 加载,可以是所需的 URL 或包含文件名的 URL。这一定是一些愚蠢的配置问题,但文档有点薄,我在这个问题上发现的其他问题也是如此。
我还尝试了 app.wsgi_app = CGIRootFix(app.wsgi_app,app_root='/')
以及我之前看到的线程的一些其他变体。
知道是什么导致我使用 CGIRootFix 时出现 404 吗?我可以做些什么来让它加载所需的 URL 页面?
我从来不知道如何让这个修复程序工作,但是,我相信这可能是因为它是一个过时的解决方案。我能够通过我的代码中的以下更改修复链接:
将 app.config['_external']=True
添加到配置中,然后在 .cgi 文件中,在应用程序执行行之前添加 os.environ['SCRIPT_NAME']=""
。您也可以将 SCRIPT_NAME=""
添加到您站点的配置中,并且只有在同时设置了 _external 时才有效。最终结果是它不起作用,我的 URL 是正确的。
真心希望这对处于相同情况的其他人有所帮助。