“重定向”简单介绍:

  “重定向”指的是HTTP重定向,是HTTP协议的一种机制。当client向server发送一个请求,要求获取一个资源时,在server接收到这个请求后发现请求的这个资源实际存放在另一个位置,于是server在返回的response中写入那个请求资源的正确的URL,并设置reponse的状态码为301(永久)或者 302(暂时),当client接受到这个response后就会根据新的URL重新发起请求。重定向有一个典型的特症,即,当一个请求被重定向以后,最终浏览器上显示的URL往往不再是开始时请求的那个URL了。这就是重定向的由来。

下面我们先看Redirect的源码,之后分析完源码后可以更好的理解其用法。

Tornado Redirect源码分析:

  在 web.py 中发现有俩个地方实现了重定向的机制:

  1. 基类 RequestHandler 中定义的 self.redirect:

 def redirect(self, url, permanent=False, status=None):
if self._headers_written:
raise Exception("Cannot redirect after headers have been written")
if status is None:
status = 301 if permanent else 302
else:
assert isinstance(status, int) and 300 <= status <= 399
self.set_status(status)
self.set_header("Location", utf8(url))
self.finish()

  先看传入进来的参数:

  • url:重定向后所返回的新的URL地址
  • permanent:默认为False,表示该重定向为临时性的;如果为True,则该重定向为永久性。
  • status:当status被指定了值的话,那个该值将会作为HTTP返回给客户端的状态码;如果没有指定特定的值,那么根据上方的permanent状态,如果permanent为True,则该status返回301;如果permanent为False,则该status返回302。

  注: 默认值为302。

  分析:

  1. 通过检测 self._headers_written 的值,来判断是否该请求已经被返回给了客户端:                                                                                                                                                                                                                                                在 基类 RequestHandler 的初始化中,self._headers_written = False,之后如果当前输出的缓冲区已经flush到了网络的时候,函数 def flush() 中会将 self._headers_written = True。所以此时头信息headers已经别写入了请求且已经返回给了客户端,是无法进行重定向了。
  2. status状态码默认为302,除非permanent参数为True(永久重定向)才会返回301。如果status指定了特定的值的话,那么对指定的值进行数据类型判断,并且status的范围为 300~399,否则会返回异常。
  3. 写入状态信息,以及 字段“Location” (用来重定向接收方到非请求URL的位置来完成请求或标识新的资源)的值
  4. 调用 finish() ,完成该HTTP请求。

  2. 类 RedirectHandler实现的重定向:

 class RedirectHandler(RequestHandler):
def initialize(self, url, permanent=True):
self._url = url
self._permanent = permanent def get(self, *args):
self.redirect(self._url.format(*args), permanent=self._permanent)

  介绍和用法:

  • 重定向客户端的GET请求到给定的URL。
  • 需要提供关键参数URL传入该处理类中,例如:
 application = web.Application([
(r"/oldpath", web.RedirectHandler, {"url": "/newpath"}),
])

   在Application中调用该 RedirectHandlerf方法,给定参数“url”,其会将 地址’/oldpath‘ 重定向到 ’/newpath‘ 中。

  • 该类也支持对重定向URL地址进行正则表达式匹配,例如为了实现交换第一个和第二个参数部分,同事保留其余部分不变: 
 application = web.Application([
(r"/(.*?)/(.*?)/(.*)", web.RedirectHandler, {"url": "/{1}/{0}/{2}"}),
])

   最终的URL可以使用格式化方法: str.format,子串会被捕获然后进行对应的匹配。在上面的例子中,一个 “a/b/c” 的请求能够被格式化,如下:   

str.format("/{1}/{0}/{2}", "a", "b", "c")  # -> "/b/a/c"

  源码分析:

  1. 通过 initiaialize() 函数进行参数 URL, permanent 的初始化。permanent初始化为True,则该重定向为永久化的。
  2. 定义 get() 函数,调用 基类中定义的 self.redirect 进行重定向的处理。

两种重定向方法的比较和思考:

  对于两种方法中的 permanent 参数,类 RedirectHandler 中默认为True(永久性重定向301);self.redirect中默认为False(临时性重定向302);

  原因:self.redirect 多数情况下被用于用户自定义的情况下进行重定向操作(例如环境变更、用户认证、以及表单提交),所以其默认为临时的重定向。类RedirectHandler 是每次匹配到该请求URL的时候就触发重定向。

  

Tornado源码分析 --- Redirect重定向的更多相关文章

  1. Tornado源码分析 --- 静态文件处理模块

    每个web框架都会有对静态文件的处理支持,下面对于Tornado的静态文件的处理模块的源码进行分析,以加强自己对静态文件处理的理解. 先从Tornado的主要模块 web.py 入手,可以看到在App ...

  2. tornado源码分析-iostream

    tornado源码分析-iostream 1.iostream.py作用 用来异步读写文件,socket通信 2.使用示例 import tornado.ioloop import tornado.i ...

  3. Tornado源码分析系列之一: 化异步为'同步'的Future和gen.coroutine

    转自:http://blog.nathon.wang/2015/06/24/tornado-source-insight-01-gen/ 用Tornado也有一段时间,Tornado的文档还是比较匮乏 ...

  4. Tornado源码分析 --- Cookie和XSRF机制

    Cookie和Session的理解: 具体Cookie的介绍,可以参考:HTTP Cookie详解 可以先查看之前的一篇文章:Tornado的Cookie过期问题 XSRF跨域请求伪造(Cross-S ...

  5. Tornado源码分析之http服务器篇

    转载自 http://kenby.iteye.com/blog/1159621 一. Tornado是什么? Facebook发布了开源网络服务器框架Tornado,该平台基于Facebook刚刚收购 ...

  6. tornado源码分析系列一

    先来看一个简单的示例: #!/usr/bin/env python #coding:utf8 import socket def run(): sock = socket.socket(socket. ...

  7. tornado源码分析

    初识tornado 首先从经典的helloword案例入手 import tornado.ioloop import tornado.web class MainHandler(tornado.web ...

  8. tornado源码分析-多进程

    1.源码文件 process.py 2.fork子进程 def fork_processes(num_processes, max_restarts=100): ... def start_child ...

  9. Tornado源码分析 --- Etag实现

    Etag(URL的Entity Tag): 对于具体Etag是什么,请求流程,实现原理,这里不进行介绍,可以参考下面链接: http://www.oschina.net/question/234345 ...

随机推荐

  1. Oracle数据类型number

    oracle数值类型只有number number(变长) 1.number可以存放整数,可以存放小数: 2.number(p,s) 说明: p表示有效位,s为小数位:范围p[1,38],s[-84, ...

  2. spring boot tomcat 线程数 修改初始线程数 统计性能 每百次请求耗时

    [root@f java]# tail -30 nohup.outsearchES-TimeMillisSpent:448P->1602@fT->http-nio-8080-exec-3t ...

  3. Redis 缓存穿透,缓存击穿,缓存雪崩的解决方案分析

    设计一个缓存系统,不得不要考虑的问题就是:缓存穿透.缓存击穿与失效时的雪崩效应. 一.什么样的数据适合缓存? 分析一个数据是否适合缓存,我们要从访问频率.读写比例.数据一致性等要求去分析.  二.什么 ...

  4. Python开发【项目】:RPC异步执行命令(RabbitMQ双向通信)

    RPC异步执行命令 需求: 利用RibbitMQ进行数据交互 可以对多台服务器进行操作 执行命令后不等待命令的执行结果,而是直接让输入下一条命令,结果出来后自动打印 实现异步操作 不懂rpc的请移步h ...

  5. git-【一】概述安装

    一:Git是什么? Git是目前世界上最先进的分布式版本控制系统. 二:SVN与Git的最主要的区别? SVN是集中式版本控制系统,版本库是集中放在中央服务器的,而干活的时候,用的都是自己的电脑,所以 ...

  6. 在python中使用c语言编写的库

    本文使用的 cffi 官网网址:https://cffi.readthedocs.io/en/latest/overview.html cffi 自己本身使用了pycparser 这个库,是用pyth ...

  7. (转)在GitHub多个帐号上添加SSH公钥

    GitHub后台可以添加多个SSH Keys,但是同一个SSH Keys只能在添加在一个帐号上(添加时提示“Key is already in use”).理由很容易想到,SSH公钥使用时相当于用户名 ...

  8. [golang grpc] 框架介绍

    官方网站 http://www.grpc.io/ http://www.grpc.io/docs/quickstart/go.html grpc安装 • go安装 目前grpc需要go 1.5以上版本 ...

  9. python3 应用 nose_parameterized 实现unittest 参数化

    一.读取变量的值,实现unittest 参数化 import nose_parameterized,unittest def calc(a:int,b:int): return a+b case_da ...

  10. Python3.x:os.mkdir与 os.makedirs(创建目录方法)区别

    Python3.x:os.mkdir与 os.makedirs区别 1,os.mkdir mkdir( path [,mode] ) 说明: 创建一个目录,可以是相对或者绝对路径,mode的默认模式是 ...