我们知道,用来传输页面的协议就是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. golang中的字符串

    0.1.索引 https://waterflow.link/articles/1666449874974 1.字符串编码 在go中rune是一个unicode编码点. 我们都知道UTF-8将字符编码为 ...

  2. go-zero docker-compose 搭建课件服务(五):完善user服务

    0.转载 go-zero docker-compose 搭建课件服务(五):完善user服务 0.1源码地址 https://github.com/liuyuede123/go-zero-course ...

  3. python实现多接口翻译软件

    本实验用pyqt5做了一个小软件,里面使用了市面上主流的6种翻译软件接口:谷歌.百度.有道.金山词霸.腾讯.必应,界面如图所示: 以下是程序代码: import time,sys,os,hashlib ...

  4. 11.-ORM-基本操作-创建数据

    一.ORM-操作 基本操作包括增删改查,即(CRUD)操作 CRUD是指在做计算处理时增加(create).读取查询(read).更新(update).删除(delete) ORM CRUD 核心 - ...

  5. UE优化性能

    UE 优化 参考:风恋残雪的博客 Stat unit 启动一个非Debug的游戏进程 打开控制台输入 Stat UNIT .PC端 ` , Android 四指点击 正常的渲染状态: 名称 功能 Fr ...

  6. Java线程未捕获异常处理 UncaughtExceptionHandler

    当一个线程在执行过程中抛出了异常,并且没有进行try..catch,那么这个线程就会终止运行.在Thread类中,提供了两个可以设置线程未捕获异常的全局处理器,我们可以在处理器里做一些工作,例如将异常 ...

  7. Java代码审计sql注入

    java_sec_code 该项目也可以叫做Java Vulnerability Code(Java漏洞代码). 每个漏洞类型代码默认存在安全漏洞(除非本身不存在漏洞),相关修复代码在注释里.具体可查 ...

  8. 一个小时,200行代码,手写Spring的IOC、DI、MVC

    一.概述 配置阶段:主要是完成application.xml配置和Annotation配置. 初始化阶段:主要是加载并解析配置信息,然后,初始化IOC容器,完成容器的DI操作,已经完成HandlerM ...

  9. K8s架构|全面整理K8s的架构介绍

    K8S架构与核心技术介绍 1. 架构图 1.1 整体结构图 1.2 组件间的协议 CNI: CNI是Container Network Interface的是一个标准的,通用的接口 ;用于连接容器管理 ...

  10. tcp/udp 协议特性和三次握手

    一.TCP/UDP协议特性1)TCP特性:工作在传输层.建立连接.可靠的.错误检查 2)UDP特性:工作在传输层.不需要连接.不可靠的.有限的错误检查.传输性能高 2.控制位及确认号解释 控制位:由6 ...