我们知道,用来传输页面的协议就是HTTP协议,全称是超文本传输协议,而浏览器展示的页面则是用HTML编写的,HTML的全称则是超文本标记语言。你看,都叫做超文本,我在第一篇文章的时候也详细的聊过,超文本区别于文本的本质就是文本中具有超链接的文本。

  当我们点击页面中的超链接,则会跳转到其它超文本页面,对于线性传统结构的文档,是一个根本性的变革。

一、重定向的基本概念和场景

  点击超链接后,浏览器会解析URL,再用这个URL发起一个新的HTTP请求,跳转到其它页面。这样的跳转动作,是由浏览器的使用者发起的,这种跳转叫做“主动跳转”,但是还有一类跳转,是由服务器发起的,浏览器使用者无法控制,也就是“被动跳转”,被动跳转在HTTP中有一个专有的名词,叫做重定向

  重定向的使用场景其实并不少,比如,多个域名指向一个统一的页面。我们可以在浏览器里打开一个新的tab标签,然后输入http://www.baidu.com,看一下,什么效果?

  我们发现会优先有两个请求,一个307,一个200。我们来看下详细的内容:

  我们看下,其实并不复杂,就是重定向到https协议的域名。

  嗯……这就是一个比较常见的重定向场景之一。再比如一些资源的更新,旧的不用了,但是为了不去修改HTML资源访问的代码,紧急解决一些问题,就可以由服务器更改,重定向到新的资源页面。

  详细的内容,我们在后续的讲解和例子中再深入的学习。

二、重定向涉及到的头字段和状态码

  我们要聊的字段其实不多,就一个,就是Location字段,Location字段可以接受绝对地址或者相对地址作为该字段的值,如果是相对地址的话,则会从响应报文的上下文中获取相应的信息,拼出完整的重定向地址。如果重定向只是在站内跳转,比如www.zaking.com跳转到www.zaking.com/index.html,那你可以随便用,但是如果你要跳到别的站点,比如从www.zaking.com跳转到www.baidu.com,则必须使用完整的绝对地址。

  涉及到重定向的状态码则比较多了,我们要能准确地区分出不同的3xx状态码代表的含义。最常见的状态码就是301、302,还有比如303,304,305,306,307我们稍微了解下,注意其语义的区别即可。

  首先,301状态码的意思是Moved Permanently,也就是永久重定向,意味着你访问的资源已经不存在了,今后所有的请求都要使用新的URI。当浏览器看到301状态码时,就知道原来的URI已经过时了,会适当的做一些优化。比如历史记录,更新书签,下次访问的时候,就不会再往旧地址发送请求了。而搜索引擎看到301,也会更新索引库,不会在去爬原来的地址了。

  当然,这里你要知道的就是,这些一切的优化也好,更新也罢,其实都是终端针对协议所做的应用层面的操作。比如,浏览器会根据301来进行优化,搜索引擎也会根据301来实现更新策略,那浏览器不实现行不行?搜索引擎也不做这些额外的无聊的操作,肯定都是可以的~~

  接下来我们说说302,是指临时重定向,也就是说你访问的地址暂时不能用了,先去新的地址访问资源吧。但由于是临时重定向,浏览器也好,搜索引擎也好,还是其它的啥啥也好,都不会做什么优化和更新,只是做个重定向的操作就完事了。

  那么我们再来看看其它的不常用的状态码:

  1. 303,没啥用~意思是See Other,参见其它的意思,但要求重定向后的请求改为 GET 方法,访问一个结果页面,避免 POST/PUT 重复操作;。其实302做的事情,跟303一样,用302就行了。
  2. 304,未修改,Not Modified,如果客户端执行了一个有条件的Get请求,但是请求的资源并没有修改,则会返回304。有条件的Get请求,其实就是指那些带有If-开头的头字段,需要根据这些字段进行一些其它的逻辑处理。了解下就行啦。
  3. 305,Use Proxy,所提供的Location字段的值必须是一个代理服务器的地址。
  4. 306,废弃了。不用管
  5. 307,Temporary Redirect,类似 302,但重定向后请求里的方法和实体不允许变动,含义比 302 更明确。

  所以你看,除了301和302意外,其它大多数的字段要么场景更细节,实践的时候大多数都由302处理了,要么就废弃了。我们熟悉301和302就足够了。

三、重定向的应用场景

  我们之前在聊状态码的时候,强调了301和302的重要性,换句话就是说,其实重定向可以粗略、简单、明了的理解为临时永久的区别。那么针对重定向的使用场景,实际上也是基于临时和永久的区别和特点来实践的。

  那什么时候需要重定向呢?一个最常见的原因就是“资源不可用”,我们需要提供一个新资源的URI来进行后续的使用。至于不可用的原因那就种类繁多千变万化了,比如服务器维护,为了用户使用不受到影响,则会重定向到一个临时的页面,供用户访问。

  另一个原因就是增加访问入口,让多个名字类似的域名指定到同一个主站,增加访问的入口同时还不会增加什么工作量。

  在确定了重定向的场景后,要考虑的就是临时还是永久了。那么针对我们上面提到的两种场景,要用临时还是永久呢?

四、例子

  我们聊完了重定向的核心概念,接下来我们就来写一写例子,在实际的代码实验中,体验下301和302的区别。按照惯例,基本的代码我就不贴在这里了,我只贴核心的部分了噢。首先,我们先来看看临时重定向:

if (parsedUrl.pathname == "/301") {
let sourceCode = fs.readFileSync(
path.resolve(__dirname, "./index.html"),
"utf8"
);
res.writeHead(301, {
Location: "http://www.zaking.com:9001/redirect"
,
});

res.end(sourceCode);
}

  其实就真的很简单,我感觉没啥说的。302的也一样,把上面的头字段改成302就好了。我感觉这例子不用写,结果我就不展示了,大家有兴趣可以自己试下,我们来看点不一样的:

  看到区别么?301临时重定向,如果你不做缓存的设置,那么浏览器会默认缓存原地址,因为浏览器认为你的重定向是临时的,我以后还是要用这个,而302浏览器压根不会缓存,因为觉得这个地址不会再用了,缓存也没用。我们再来看个例子:

// 死循环了
if (parsedUrl.pathname == "/cycle") {
let sourceCode = fs.readFileSync(
path.resolve(__dirname, "./cycle.html"),
"utf8"
);
res.writeHead(302, {
Location: "http://www.zaking.com:9001/back",
});
res.end(sourceCode);
}
if (parsedUrl.pathname == "/back") {
let sourceCode = fs.readFileSync(
path.resolve(__dirname, "./back.html"),
"utf8"
);
res.writeHead(302, {
Location: "http://www.zaking.com:9001/cycle",
});
res.end(sourceCode);
}

  代码没啥哈,重点在于循环跳转,直接造成浏览器压根没法用:

  这是重定向需要尤其注意的问题,咱们现在的重定向链路十分简单,就两个页面来回跳,当你写了复杂的服务器逻辑的时候,很难确定是否会有循环链路的重定向的。

五、总结

  其实关于重定向,最核心的就是301和302了,大家一定要会,没啥好说的。重定向在一定程度上解决了一些场景下的应用方案,但是其实也带来一定的问题,比如,只要重定向就一定会发送一次额外的请求,造成性能的浪费。另外要格外注意的就是循环跳转的问题。

  本篇的东西不多,那就到这里啦,学习这么无聊,下一篇我们来吃点点心。

真正“搞”懂HTTP协议08之重定向的更多相关文章

  1. 真正“搞”懂HTTP协议02之空间穿梭

    时隔四年,这个系列鸽了四年,我终于觉得我可以按照自己的思路和想法把这个系列完整的表达出来了. 想起四年前,那时候还是2018年的六月份,那时候我还工作不到两年,那时候我翻译了RFC2616的部分内容, ...

  2. 真正“搞”懂http协议01—背景故事

    去年读了<图解HTTP>.<图解TCP/IP>以及<图解网络硬件>但是读了之后并没有什么深刻的印象,只是有了一层模糊的脉络,刚好最近又接触了一些有关http的相关内 ...

  3. 真正“搞”懂HTTP协议03之时间穿梭

    上一篇我们简单的介绍了一下DoD模型和OSI模型,还着重的讲解了TCP的三次握手和四次挥手,让我们在空间层面,稍稍宏观的了解了HTTP所依赖的底层模型,那么这一篇,我们来追溯一下HTTP的历史,看一看 ...

  4. 搞懂Redis协议RESP

    RESP (REdis Serialization Protocal) Redis客户端和服务端之间通信的协议.它很简单,建立在TCP协议上,提供简单.高性能.可读性强的数据序列化的规范和语义. 5种 ...

  5. 搞懂分布式技术4:ZAB协议概述与选主流程详解

    搞懂分布式技术4:ZAB协议概述与选主流程详解 ZAB协议 ZAB(Zookeeper Atomic Broadcast)协议是专门为zookeeper实现分布式协调功能而设计.zookeeper主要 ...

  6. 搞懂分布式技术2:分布式一致性协议与Paxos,Raft算法

    搞懂分布式技术2:分布式一致性协议与Paxos,Raft算法 2PC 由于BASE理论需要在一致性和可用性方面做出权衡,因此涌现了很多关于一致性的算法和协议.其中比较著名的有二阶提交协议(2 Phas ...

  7. [转帖]USB-C和Thunderbolt 3连接线你搞懂了吗?---没搞明白.

    USB-C和Thunderbolt 3连接线你搞懂了吗? 2018年11月25日 07:30 6318 次阅读 稿源:威锋网 3 条评论 按照计算行业的风潮,USB Type-C 将会是下一代主流的接 ...

  8. [转帖]从HTTP/0.9到HTTP/2:一文读懂HTTP协议的历史演变和设计思路

    从HTTP/0.9到HTTP/2:一文读懂HTTP协议的历史演变和设计思路   http://www.52im.net/thread-1709-1-2.html     本文原作者阮一峰,作者博客:r ...

  9. 搞懂分布式技术21:浅谈分布式消息技术 Kafka

    搞懂分布式技术21:浅谈分布式消息技术 Kafka 浅谈分布式消息技术 Kafka 本文主要介绍了这几部分内容: 1基本介绍和架构概览 2kafka事务传输的特点 3kafka的消息存储格式:topi ...

  10. 搞懂分布式技术28:微服务(Microservice)那点事

    搞懂分布式技术28:微服务(Microservice)那点事 微服务(Microservice)那点事 肥侠 2016-01-13 09:46:53 浏览58371 评论15 分布式系统与计算 微服务 ...

随机推荐

  1. 从源码入手探究一个因useImperativeHandle引起的Bug

    今天本来正在工位上写着一段很普通的业务代码,将其简化后大致如下: function App(props: any) { // 父组件 const subRef = useRef<any>( ...

  2. pta第一次博客

    目录 pta第一次博客 1.前言 2.设计与分析 第二次作业第二题 第三次作业第一题 第三次作业第二题 第三次作业第三题 3.踩坑心得: 4.改进建议 5.总结 pta第一次博客 1.前言 这三次pt ...

  3. centos 7.6镜像_Centos7 配置本地yum源为iso镜像

    创建挂载路径 sudo mkdir /media/iso 挂载ISO镜像到目录 sudo mount -o loop CentOS-7-x86_64-Minimal-1810.iso /media/i ...

  4. ThreadPoolExecutor BlockingQueue讲解

    有四种常用阻塞队列策略: 1.直接拒绝:(Direct Handoffs) 一个好的工作队列应该是不缓存任务,而是直接交给线程处理,就如SynchronousQueue一样.一个任务将会入队失败,如果 ...

  5. 「浙江理工大学ACM入队200题系列」问题 F: 零基础学C/C++39——求方程的解

    本题是浙江理工大学ACM入队200题第四套中的F题 我们先来看一下这题的题面. 由于是比较靠前的题目,这里插一句.各位新ACMer朋友们,请一定要养成仔细耐心看题的习惯,尤其是要利用好输入和输出样例. ...

  6. [数据结构-线性表1.2] 链表与 LinkedList<T>(.NET 源码学习)

    [数据结构-线性表1.2] 链表与 LinkedList<T> [注:本篇文章源码内容较少,分析度较浅,请酌情选择阅读] 关键词:链表(数据结构)    C#中的链表(源码)    可空类 ...

  7. Oracle 表空间常用操作

    aliases: [Oracle表空间] tags:      [数据库,Oracle,Blog] summary: [Oracle表空间常用操作,包括查询.分析.扩容.删除.优化等] date:   ...

  8. 2022春每日一题:Day 26

    题目:无聊的数列 区间增加等差序列,似乎不好维护,等差等差,那就差分呗,单点查询,更加肯定,直接差分,每次加了一个等差序列容易发现只需要对应的差分数组a[l]+=k,a[l+1]...a[r]+=d, ...

  9. mysql 基础明细

    1.mysql 没有 TOP,用limit实现 2.mysql having 聚合之后,对组操作,和GROUP By搭配 mysql where  聚合之前,对表和视图操作 3.where 子句的作用 ...

  10. i春秋GetFlag

    进去是个提示界面,提示我们这是个迷你文件管理系统,我们需要登录然后下载文件再获得flag. 然后我们查看源码,没什么信息,点login进去查看源码,没什么信息 下方出现了一个substr(md5(ca ...