在Bluehost的子目录上部署Flask碰到url重定向难题
Bluehost的主机一般web的根目录是public_html(别名是www)。由于根目录下面放的是网站首页,不能乱动,因此为了部署新的应用,我在public_html下建了app这个目录。
- 在app下设置.htaccess,内容如下:
Options +ExecCGI
AddHandler fcgid-script .fcgi
RewriteEngine On
RewriteBase /app/
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ index.fcgi/$1 [QSA,L]
- 在app下设置index.fcgi,内容如下:
#!/mypath_to_python
import sys
sys.path.insert(0, '/mypath_to_site-packages')
from flup.server.fcgi import WSGIServer
from index import app
class ScriptNameStripper(object):
def __init__(self, app):
self.app = app
def __call__(self, environ, start_response):
environ['SCRIPT_NAME'] = ''
return self.app(environ, start_response)
app = ScriptNameStripper(app)
if __name__ == '__main__':
WSGIServer(app).run()
- 部署一个简单的hello world应用,index.py,内容如下:
from flask import Flask
app = Flask(__name__)
@app.route("/")
def hello():
return "Hello World!"
if __name__ == "__main__":
app.run()
输入http://abc.com/app,一切正常。
于是我开始增加一个登录功能,当用户访问首页http://abc.com/app时,如果发现用户没有登录,自动跳转到http://abc.com/app/login。于是我改写了index.py如下:
from flask import Flask, request, url_for, render_template, redirect, session
app = Flask(__name__, static_url_path='/static')
@app.route('/', methods=['GET'])
def home():
if not session.get('user'):
return redirect(url_for('login'))
else:
return render_template('home.html')
@app.route('/login', methods=['GET', 'POST'])
def login():
if request.method == 'GET':
return app.send_static_file('login.html')
else:
user = request.form.get('user')
password = request.form.get('password')
if user == 'joy' and password == 'joy':
session['user'] = user
return render_template('home.html')
else:
return 'LOGIN FAILED'
部署的目录结构如下:
public_html (对应abc.com)
|--app (这里对应abc.com/app)
|--.htaccess
|--index.fcgi
|--index.py
|--static
|--login.html
|--templates
|--home.html
就这么一个简单的应用,部署上去以后,访问http://abc.com/app,本来期望的效果是直接跳转到http://abc.com/app/login,加载静态登陆页面login.html,让用户属于登录信息。但实际得到的效果确是跳转到http://abc.com/login,导致了404找不到页面的错误。我试了很多很多方法,都没搞定,求助大家。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
不要尝试把 Web 程序挂载到子目录,除非这个 Web 程序显式地支持这样做。
一种可行的办法是挂载到特定的域名;另一种办法是通过配置项使得 Flask 里使用修改过的 URL,比如定义
然后在路由的时候使用
URL_PREFIX + '/login'
这样。你可以自定义一个 blueprint,覆写其 route 方法来自动给 endpoint 添加前缀。当然还有个办法是自己实现
url_for
,但是你不一定能做好。更新:
试试设置
APPLICATION_ROOT
配置项。