通过HTTP包来再次理解重定向与转发

之所以去看它们之间数据包的差异并不是好奇。我理解它们之间的差异,但是我不知道该如何证明它们之间的差异。想了很久,我觉得去抓包,看它们之间数据包之间的差异,就是一个有力的证据。

预设

总共有三个servlet,即/ddgg_ssm/loginre//ddgg_ssm/loginzf/ddgg_ssm/user/,它们的作用依次为重定向到/ddgg_ssm/user/、转发到/ddgg_ssm/user/、显示一串字符。简要代码如下: 重定向

@Controller
@RequestMapping("/loginre")
public class LoginController {
	@RequestMapping("/*")
	@ResponseBody
	public void printMsg(HttpServletRequest request, HttpServletResponse response) {
		try {
			response.sendRedirect("/ddgg_ssm/user/");
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
}

转发

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    request.getRequestDispatcher("/user/").forward(request, response);
}

先进行的是重定向,再接着的是转发。

数据包抓取结果以及简要的分析

重定向与转发的数据包如下:

重定向与转发的HTTP数据包分析

首先是第一个数据包,请求loginre

GET /ddgg_ssm/loginre/ HTTP/1.1
Host: 172.10.1.39:8080
Connection: keep-alive
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Linux; U; Android 7.0; zh-cn; Redmi Note 4X Build/NRD90M) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/61.0.3163.128 Mobile Safari/537.36 XiaoMi/MiuiBrowser/9.7.2
x-miorigin: b
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,en-US;q=0.8
Cookie: JSESSIONID=3AFB73B954FEA21EA30E9F1D5ECF63A4

得到服务器的302重定向响应

HTTP/1.1 302 
Location: /ddgg_ssm/user/
Content-Length: 0
Date: Tue, 05 Jun 2018 09:04:57 GMT

浏览器得到重定向的响应后,再请求Location中的Servlet

GET /ddgg_ssm/user/ HTTP/1.1
Host: 172.10.1.39:8080
Connection: keep-alive
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Linux; U; Android 7.0; zh-cn; Redmi Note 4X Build/NRD90M) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/61.0.3163.128 Mobile Safari/537.36 XiaoMi/MiuiBrowser/9.7.2
x-miorigin: b
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,en-US;q=0.8
Cookie: JSESSIONID=3AFB73B954FEA21EA30E9F1D5ECF63A4

最后再得到服务器的响应:

HTTP/1.1 200 
Content-Type: text/html;charset=ISO-8859-1
Content-Length: 12
Date: Tue, 05 Jun 2018 09:04:57 GMT

Hello World!

此时浏览器的地址栏已经变成了/ddgg_ssm/user/


而后续的转发,只有两个数据包,一个请求与一个响应。

GET /ddgg_ssm/loginzf HTTP/1.1
Host: 172.10.1.39:8080
Connection: keep-alive
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Linux; U; Android 7.0; zh-cn; Redmi Note 4X Build/NRD90M) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/61.0.3163.128 Mobile Safari/537.36 XiaoMi/MiuiBrowser/9.7.2
x-miorigin: b
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,en-US;q=0.8
Cookie: JSESSIONID=3AFB73B954FEA21EA30E9F1D5ECF63A4

得到的响应是/ddgg_ssm/user/所写入的内容Hello world!

HTTP/1.1 200 
Content-Type: text/html;charset=ISO-8859-1
Content-Length: 12
Date: Tue, 05 Jun 2018 09:05:28 GMT

Hello World!

再贴一个结论吧

  • 转发在服务器端完成的;重定向在客户端完成
  • 转发的是同一次请求;重定向是两次不同请求
  • 转发地址栏没有变化;重定向地址栏有变化

Read more

Volcano 与 Kubernetes GPU 调度学习笔记

本笔记系统整理 Volcano 调度器、Kubernetes 调度框架、GPU Device Plugin、HAMi 等云原生 AI 调度领域的核心知识,适合用于学习、复习和工程实践参考。 目录 * 第一部分:Volcano 入门 * 1. Volcano 是什么 * 2. 安装与快速使用 * 3. 核心特性一览 * 第二部分:Volcano 整体架构 * 4. Volcano 解决的核心问题 * 5. 整体架构与数据流 * 6. 三层抽象模型 * 第三部分:Volcano 核心实现原理 * 7. Session 机制 * 8. Gang Scheduling 实现 * 9. Queue 与 DRF 公平调度

容器镜像(4):镜像的常用工具箱

容器镜像(4):镜像的常用工具箱

前几篇在讲多架构镜像时已经用过 skopeo 和 crane 做镜像复制,这篇系统整理这两个工具的完整能力,同时介绍几个日常操作镜像时同样好用的工具。 一、skopeo:不依赖 Daemon 的镜像瑞士军刀 skopeo 的核心价值是绕过 Docker daemon,直接与 Registry API 交互。上一篇用它做镜像复制和离线传输,但它的能力远不止于此。 1.1 安装 # Ubuntu / Debian sudo apt install -y skopeo skopeo --version # skopeo version 1.15.1 1.2 inspect:免拉取检查镜像元数据 docker inspect 需要先把镜像拉到本地,skopeo inspect 直接向 Registry

容器镜像(3):多架构镜像构建

容器镜像(3):多架构镜像构建

一、什么是多架构镜像 1.1 OCI Image Index 上一篇介绍了单平台镜像的结构:一个 Manifest 指向 Config 和若干 Layer blob。多架构镜像在此之上多了一层——OCI Image Index(也叫 Manifest List),是一个轻量的索引文件,把多个单平台 Manifest 组织在一起: $ docker manifest inspect golang:1.22-alpine { "schemaVersion": 2, "mediaType": "application/vnd.oci.image.index.v1+json", "manifests&

容器镜像(2):containerd 视角下的镜像

容器镜像(2):containerd 视角下的镜像

一、为什么需要了解 containerd 如果你只用 docker run 跑容器,从来不关心底层,那可以不了解 containerd。但如果你在用 Kubernetes,或者想真正理解"容器运行时"是什么,containerd 是绕不开的。 事实上,当你执行 docker run 的时候,containerd 早就在后台悄悄工作了——Docker 从 1.11 版本开始,就把核心运行时剥离出来交给 containerd 负责。 1.1 Docker 的架构演变 早期的 Docker(1.10 及之前)是一个"大一统"的单体程序:一个 dockerd