记录一些Tornado中的常用知识。
- 获取远端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() %}会在模板页面中直接生成一个
<input type="hidden" name="_xsrf" value="2|16ecb15b|07a3a51e047a34f944eef2b6b4e5e017|1439262852"/>
这样一个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相关,回头看完也记录一下。