Функция url_for во Flask не работает для развертывания поддомена на Bluehost

Я развернул очень простое приложение Flask под названием «app» в подкаталоге корневого каталога в Bluehost. Надеюсь, example.com указывает на домашнюю страницу, а example.com/app указывает на мое приложение Flask. На самом деле приложение Flask отлично работает, когда скрипт index.py выглядит так:

from flask import Flask

app = Flask(__name__)

@app.route('/', methods=['GET'])
def home():
    return 'Hello world'

if __name__ == "__main__":
    app.run()

Но все пошло не так, когда я представил простую функцию входа в систему со структурой документа и index.py, выглядящей так:

структура документа:

public_html                     
|--app                          
     |--.htaccess
     |--index.fcgi
     |--index.py
     |--static
        |--login.html
     |--templates
        |--home.html

index.py:

from flask import Flask, url_for, request, render_template, redirect, session
app = Flask(__name__)

@app.route('/', methods=['GET'])
def home():
    if not session.get('user'):
        return redirect(url_for('login'))     #go to login page if not logined
    else:
        return render_template('home.html')   #otherwise go to home page

@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'

if __name__ == "__main__":
    app.run()

Однако доступ к example.com/app привел к изменению URL-адреса на example.com/login и к разумной ошибке 404, поскольку example.com/login не сопоставляется ни с одним документом.

return redirect(url_for('login'))

url_for ('login') возвращает example.com/login вместо example.com/app/login. Вот почему последняя версия index.py не работает. Я перепробовал так много вещей, но ничего не нашел. Пожалуйста помоги. Благодарность!

Мой .htaccess:

Options +ExecCGI
AddHandler fcgid-script .fcgi
RewriteEngine On
#RewriteBase /app/        # Neither RewriteBase / or RewriteBase /app/  work
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ index.fcgi/$1 [QSA,L]

Мой index.fcgi:

import sys
sys.path.insert(0, '/path_to_my_python_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()

person Joy Woo    schedule 01.05.2015    source источник
comment
я бы сказал, что rewriteBase - это то, что вам нужно (документы)   -  person Nikos M.    schedule 01.05.2015


Ответы (2)


Следующее работает для меня сейчас.

  1. Комментарий RewriteBase в .htaccess

  2. Обновлен index.py с настроенным url_for

    from flask import Flask, redirect, url_for
    
    app = Flask(__name__)
    
    def strip_url(orig):
       return orig.replace('index.fcgi/', '')
    
    @app.route('/', methods=['GET'])
    def home():
        return redirect(strip_url(url_for('login')))
    
    @app.route('/login', methods=['GET'])
    def login():
        return 'please login'
    
    if __name__ == "__main__":
        app.run()
    

Если необходимо сделать вывод, я бы хотел сказать официальные документы Flask fastcgi требует RewriteRule для удаления ***. fcgi из URL-адреса, который не работает для перенаправления, инициированного из кода.

person Joy Woo    schedule 02.05.2015

Установите APPLICATION_ROOT в конфигурации вашего Flask:

app.config["APPLICATION_ROOT"] = "/app"

Не используйте RewriteBase, Flask необходимо знать о корневом URL-адресе для создания URL-адресов.

person nathancahill    schedule 01.05.2015
comment
Спасибо! Простое отключение RewriteBase улучшило его, но возникла другая проблема с перезаписью URL-адресов, example.com/app был преобразован в example.com/app/index.fcgi, а url_for перенаправления ('login') был направлен на example.com/app/index.fcgi /авторизоваться. Это действительно работает даже недостаточно изящно. Итак, наконец, мой обходной путь - это настраиваемый url_for, который находит index.fcgi в URL-адресе и заменяет его пустым. - person Joy Woo; 02.05.2015
comment
Значит, не работает, если вы используете RewriteBase / и APPLICATION_ROOT = "/app"? Ваша strip_url функция не нужна. - person nathancahill; 02.05.2015