记录一些Tornado中的常用知识。


  1. 获取远端IP,直连tornado,用self.request.remote_ip,如果是走nginx反向代理方式,需要在nginx中的Server/Location配置如下

                proxy_pass http://data.xxx.com;
                #proxy_redirect off;
                proxy_set_header Host $host;
                proxy_set_header X-Real-IP $remote_addr;
                proxy_set_header REMOTE-HOST $remote_addr;
                proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

然后在tornado中使用self.request.headers['X-Real-IP']或self.request.headers['X-Forward-For']获取用户真实IP


2. 获取checkbox中的多项,单个表单变量的获取在tornado中用self.get_argument("input_name")获取,多个相同名字的变量使用self.get_arguments("input_name")获取,比如,则使用self.get_arguments('ck')获取到一个list里面。这里跟php的区别是,chekbox的变量名后面不能带方括号。比如,在php里checkbox需要写成ck[],但是在tornado里不需要这样写。


3. RequestHandler中的set_cookie和set_secure_cookie可以设定cookie过期时间,使用set_secure_cookie('name','value', expires_days=None)设置关闭即销毁,或者设置一个×××的数字为过期的天数。


4. 对于_xsrf的cookie处理,在笔记一中已经记录,{% module xsrf_form_html() %}会在模板页面中直接生成一个

这样一个hidden元素,其中的value每次刷新页面,hash值都不一样,这个hash值是根据时间戳,version,token和binascii.b2a_hex和a2b_hex来进行加解密计算的。这个扯远了,主要是想记录在前端如果用jquery的post或get,如何获取这个token。按照tornado官方文档的做法试了一下,貌似不行,可能是文档的更新没有跟上代码的更新,也可能是我自己前端水平不行,反正是没成功。

tornado官方获取页面中的_xsrf做法如下。

function getCookie(name) {
    var r = document.cookie.match("\\b" + name + "=([^;]*)\\b");
    return r ? r[1] : undefined;
}

jQuery.postJSON = function(url, args, callback) {
    args._xsrf = getCookie("_xsrf");
    $.ajax({url: url, data: $.param(args), dataType: "text", type: "POST",
        success: function(response) {
        callback(eval("(" + response + ")"));
    }});
};

后来换了个方法,用jquery直接获取页面中的元素名称的value,而不去读取cookie的值,确实是前端水平不行,或许这样会不安全吧。

xsrf = $('input[name=_xsrf]').val();

这样就可以取到_xsrf的值,并进行$.post操作。


5. 清除cookie,之前网上有文章说清除tornado的cookies是将set_cookie('name','value')方法里面的对应name的value设置为空。实际上,tornado源码中提供了清除cookie的方法。

def clear_cookie(self, name, path="/", domain=None):
        """Deletes the cookie with the given name.

        Due to limitations of the cookie protocol, you must pass the same
        path and domain to clear a cookie as were used when that cookie
        was set (but there is no way to find out on the server side
        which values were used for a given cookie).
        """
        expires = datetime.datetime.utcnow() - datetime.timedelta(days=365)
        self.set_cookie(name, value="", path=path, expires=expires,
                        domain=domain)

def clear_all_cookies(self, path="/", domain=None):
        """Deletes all the cookies the user sent with this request.

        See `clear_cookie` for more information on the path and domain
        parameters.

        .. versionchanged:: 3.2

           Added the ``path`` and ``domain`` parameters.
        """
        for name in self.request.cookies:
            self.clear_cookie(name, path=path, domain=domain)

清除给定名称的cookie和清除全部cookie。


这两天在看websocket和long polling相关,回头看完也记录一下。