编写Tornado模板以使用nginx代理位置

时间:2017-10-30 21:35:46

标签: python nginx tornado

我有一个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或Tornado处理这个问题?

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

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>

在模板中。

1 个答案:

答案 0 :(得分:0)

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

如果您仍然想要使用不同的路径,具体取决于您是否通过nginx,我会建议您使用URL帮助程序功能。其他选项包括始终在您的网址中使用相对路径而不是绝对路径(可能需要使用/home/myapp/代替主页/和{{1}},或者让nginx重写您的链接,如this question