HTTP学习笔记(五)

重定向的过程

相关字段

  • Location:(响应字段)取值为其他的路由地址。只有配合 301/302 状态码才有意义,它标记了服务器要求重定向的 URI。浏览器收到 301/302 报文,会检查响应头里有没有“Location”。如果有,就从字段值里提取出 URI,发出新的 HTTP 请求,相当于自动替我们点击了这个链接。
    • 取值可以是相对或者绝对路径。
      • 相对url浏览器可自动拼接
      • 绝对url必须完整,包括协议、域名、端口、路径等
    • 重定向可以把一个 URI 指向另一个 URI,也可以把多个 URI 指向同一个 URI,用途很多;
  • Refresh:(响应字段)实现延时重定向,例如“Refresh: 5; url=xxx”告诉浏览器5秒钟后再跳转。
1
Refresh: 1,url=/index
1
2
3
4
5
6
7
8
9
const router = require('koa-router')()
router.get('/', async ({ request, response }, next) => {
response.status = 301;
response.set("Refresh", '5,url=/index')
})
router.get('/index', async ({ request, response }, next) => {
response.body = 'success'
})
module.exports = router

相关状态码

  • 301:(Moved Permanently)“永久重定向”,意思是原 URI 已经“永久”性地不存在了,今后的所有请求都必须改用新的 URI。
    • 浏览器遇见301,会做适当的优化。比如历史记录、更新书签,下次可能就会直接用新的 URI 访问,省去了再次跳转的成本。搜索引擎的爬虫看到 301,也会更新索引库,不再使用老的 URI。
  • 302:(“Moved Temporarily”)“临时重定向”,原 URI 处于“临时维护”状态,新的 URI 是起“顶包”作用的“临时工”。
    • 浏览器或者爬虫看到 302,会认为原来的 URI 仍然有效,但暂时不可用,所以只会执行简单的跳转页面,不记录新的 URI,也不会有其他的多余动作,下次访问还是用原 URI。
  • 303:(See Other)类似 302,但要求重定向后的请求改为 GET 方法,访问一个结果页面,避免 POST/PUT 重复操作;
  • 307:(Temporary Redirect)类似 302,但重定向后请求里的方法和实体不允许变动,含义比 302 更明确;
  • 308:(Permanent Redirect)类似 307,不允许重定向后的请求变动,但它是 301“永久重定向”的含义。
    • 303,307,308这三个状态码的接受程度较低,有的浏览器和服务器可能不支持,开发时应当慎重,测试确认浏览器的实际效果后才能使用。

应用场景

  • 当前资源不可用,需要另一个URL来代替。
    • 域名变更
    • 服务器变更
    • 网站改版
    • 系统维护
    • 这些都会导致原 URI 指向的资源无法访问,为了避免出现 404,就需要用重定向跳转到新的 URI,继续为网民提供服务。
  • 避免重复
    • 让多个网址都跳转到一个 URI,增加访问入口的同时还不会增加额外的工作量。
    • 有的网站都会申请多个名称类似的域名,然后把它们再重定向到主站上。

301和302的选择

永久

301

如果域名、服务器、网站架构发生了大幅度的改变,比如启用了新域名、服务器切换到了新机房、网站目录层次重构,这些都算是“永久性”的改变。原来的 URI 已经不能用了,必须用 301“永久重定向”,通知浏览器和搜索引擎更新到新地址,这也是搜索引擎优化(SEO)要考虑的因素之一。

临时

302

原来的 URI 在将来的某个时间点还会恢复正常,

  • 常见的应用场景就是系统维护,把网站重定向到一个通知页面,告诉用户过一会儿再来访问。
  • 另一种用法就是“服务降级”,比如在双十一促销的时候,把订单查询、领积分等不重要的功能入口暂时关闭,保证核心服务能够正常运行

重定向的相关问题

性能损耗

很明显,重定向的机制决定了一个跳转会有两次请求 - 应答,比正常的访问多了一次。

虽然 301/302 报文很小,但大量的跳转对服务器的影响也是不可忽视的。站内重定向还好说,可以长连接复用,站外重定向就要开两个连接,如果网络连接质量差,那成本可就高多了,会严重影响用户的体验。

所以重定向应当适度使用,决不能滥用。

循环跳转

如果重定向的策略设置欠考虑,可能会出现“A=>B=>C=>A”的无限循环,不停地在这个链路里转圈圈

所以 HTTP 协议特别规定,浏览器必须具有检测“循环跳转”的能力,在发现这种情况时应当停止发送请求并给出错误提示。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
const router = require('koa-router')()
router.get('/', async ({ request, response }, next) => {
response.status = 301;
response.set("Location", '/index')
})
router.get('/index', async ({ request, response }, next) => {
response.status = 301;
response.set("Location", '/string')
})
router.get('/string', async ({ request, response }, next) => {
response.status = 301;
response.set("Location", '/')
})
module.exports = router

结果如下:

循环重定向

其他知识补充

  • 网页的入链接和出链接
    • 入链接:可理解为导航网站跳转到本站。、
      • 入站链接很重要,因为它们通常被认为是对网站爬虫的最大指示,表明你的网站在某个主题上是一个权威。来自高质量、高权威网站的内向链接越多,你的网站的排名就越能排在Google搜索结果页面(SERP)的前面。
    • 出链接:从本找跳转到其他网站。(网站的出站链接是其他网站的入站链接)
  • “300 Multiple Choices”也是一个特殊的重定向状态码,它会返回一个有多个链接选项的页面,由用户自行选择要跳转的链接,用的较少。
  • 与跳转有关的还有一个“Referer”和“Referrer-Policy”(注意前者是个拼写错误,但已经“将错就错”),表示浏览器跳转的来源(即引用地址),可用于统计分析和防盗链。
  • 301/302重定向是由浏览器执行的,对于服务器来说可以称为“外部重定向”,相应的也就有服务器的“内部重定向”,直接在服务器内部跳转URI,将重定向的资源返回给客户端,因为不会发出HTTP请求,所以没有额外的性能损失。