编写龙卷风模板以使用 nginx 代理位置



我有一个Tornado应用程序,我想用nginx托管在非root位置下。 所以我有一个 nginx 配置,看起来像

server {
    listen 80;
    server_name mysite.com;
    location /myapp/ {
        proxy_pass http://localhost:8888/;
    }
}

我希望该应用程序存在于mysite.com/myapp/。 使用当前配置,所有处理程序都将路由到正确的URL,但是模板中使用的所有链接都是错误的。 例如

<a href='/'>Home</a>

链接到mysite.com/而不是mysite.com/myapp/。 我还希望该应用程序仍然可以在本地运行,因此我不希望/myapp/硬编码到模板中。

有没有办法用nginx或龙卷风来处理这个问题?

到目前为止,我的解决方案是向模板命名空间添加一个便利函数

import tornado.ioloop
import tornado.web
import os
APPLICATION_ROOT = os.environ.get('MYAPP_ROOT')
class BaseHandler(tornado.web.RequestHandler):
    def full_url(self, path, *args, **kwargs):
        if path.startswith('/'):
            path = path.lstrip('/')
            return os.path.join(APPLICATION_ROOT, path)
        else:
            return path
    def get_template_namespace(self):
        """Returns a dictionary to be used as the default template namespace.
        May be overridden by subclasses to add or modify values.
        The results of this method will be combined with additional
        defaults in the `tornado.template` module and keyword arguments
        to `render` or `render_string`.
        """
        namespace = dict(
            handler=self,
            request=self.request,
            current_user=self.current_user,
            locale=self.locale,
            _=self.locale.translate,
            pgettext=self.locale.pgettext,
            static_url=self.static_url,
            xsrf_form_html=self.xsrf_form_html,
            reverse_url=self.reverse_url,
            full_url=self.full_url
        )
        namespace.update(self.ui)
        return namespace

并将MYAPP_ROOT='/myapp/'设置为环境变量并使用

<a href="{{ full_url('/') }}">Home</a>

在模板中。

> Tornado 对可以像这样重新定位到不同路径的应用程序没有很好的支持 - 通常假设路径前缀是已知的并且可以硬编码。(nginx proxy_pass指令中的尾部斜杠很重要 - 删除它,nginx 将请求按原样传递给 Tornado)

如果您仍然想根据是否通过nginx使用不同的路径,我建议您使用此处的URL辅助程序函数。其他选项包括始终在URL中使用相对路径而不是绝对路径(可能需要使用/myapp/home/home而不是主页的/myapp//),或者让nginx重写您的链接,如本问题所示

最新更新