我们知道,用来传输页面的协议就是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. C# 6.0 添加和增强的功能【基础篇】

    C# 6.0 是在 visual studio 2015 中引入的.此版本更多关注了语法的改进,让代码更简洁且更具可读性,使编程更有效率,而不是和前几个版本一样增加主导性的功能. 一.静态导入 我们都 ...

  2. 二十六、StatefulSet资源控制器

    StatefulSet资源控制器 一.statefulset介绍 StatefulSet 是为了解决有状态服务的问题而设计的资源控制器. 匹配 Pod name ( 网络标识 ) 的模式为:(stat ...

  3. 如何在CentOS7上搭建自己的GitLab仓库

    序言 各位好啊,我是会编程的蜗牛,作为java开发者,在团队开发中,一般都是需要使用git及git仓库来管理我们的代码的,这非常方便.我以前在小公司的时候,基本都是一个人开发一个项目,所以也没有怎么接 ...

  4. 「浙江理工大学ACM入队200题系列」问题 J: 零基础学C/C++83——宁宁的奥数路

    本题是浙江理工大学ACM入队200题第八套中的J题 我们先来看一下这题的题面. 题面 题目描述 宁宁参加奥数班,他遇到的第一个问题是这样的:口口口+口口口=口口口,宁宁需要将1~9 九个数分别填进对应 ...

  5. 【深入浅出 Yarn 架构与实现】2-2 Yarn 基础库 - 底层通信库 RPC

    RPC(Remote Procedure Call) 是 Hadoop 服务通信的关键库,支撑上层分布式环境下复杂的进程间(Inter-Process Communication, IPC)通信逻辑, ...

  6. Java-ArrayList应用

    存储随机数字 ArrayListRandom.java package cn.day04; import java.util.ArrayList; import java.util.Random; p ...

  7. Codeforces Round #836 (Div. 2) A-D

    比赛链接 A 题意 给一个字符串 \(s\) ,对其加倍,即每个字符后面追加一个相同字符. 加倍后可以重排列,要求构造一个回文串. 题解 知识点:构造. 既然可以重排列了,那顺序是随意的了,直接翻转加 ...

  8. esp-01和esp-01s烧录固件和程序

    准备工具 USB-TTL 杜邦线若干 esp-01s烧录固件 我烧录的固件是 micropython, 使用的软件是 uPyCraft esp-01s烧录固件接线方法: esp-01s usb-ttl ...

  9. day29 jQuery选择器 & jquery属性操作 & jquery DOM元素 操作与遍历

    简介 jQuery,顾名思义,就是javascript和query(查询),即辅助javascript开发的库,本质就是一个js文件: jQuery是一个js函数库,是目前全球范围内最流行.用的最多的 ...

  10. 【Shell案例】【wc记录单词长度、for循环和if、awk文本分析工具】7、打印字母数小于8的单词

    描述写一个 bash脚本以统计一个文本文件 nowcoder.txt中字母数小于8的单词. 示例:假设 nowcoder.txt 内容如下:how they are implemented and a ...