HTTP拾技杂谈

HTTP拾技杂谈

简单聊聊HTTP中的那些东西


文章目录


前言

超文本传输协议(Hypertext Transfer Protocol ,HTTP)是一个标准,定义了Web客户端如何与服务器对话,以及数据如何从服务器传回客户端。尽管通常任务HTTP是一种传输HTML文件以及文件中内嵌图片的方法,但实际上HTTP是一个数据格式。------《java网络编程》


HTTP协议

HTTP连接使用TCP/IP来传输数据。

1.请求从客户端到服务器端的4个步骤

  1. 默认情况下,客户端在80端口与服务器打开一个TCP连接,URL可以指定其他端口
  2. 客户端向服务器发送消息,请求指定路径上的资源。请求分为首部、可选地址、请求数据。
  3. 服务器向客户端回复响应。以响应码开头,后面是包含元数据的首部、一个空行、所请求的文档(数据)或错误消息。
  4. 服务器关闭连接。
    以上就是基本HTTP1.0过程,在HTTP1.1及以后版本中,可以复用TCP连接实现发送多个请求。在1.1中请求和响应可以分为多个块发送。

一般客户端请求如下:

java 复制代码
POST /api/data HTTP/1.1          # 请求行(方法 + URI + HTTP版本)
Host: www.example.com            # 目标主机(必需首部)
User-Agent: Mozilla/5.0          # 客户端标识
Content-Type: application/json   # 消息体格式说明
Content-Length: 27               # 消息体字节长度(必需首部)
Accept: application/json         # 期望的响应格式
Authorization: Bearer abc123     # 认证令牌
Connection: keep-alive           # 连接控制
                                  #注意这里的空一行是标准
{"key": "value", "num": 42}      # 消息体(实际传输的数据)

第一行为请求行,包括方法、从服务器获取资源路径以及HTTP版本。

其他则是以 Key:Value组成的信息。

像User-Agent代表浏览器版本,host服务器名,Accept,告诉服务器,客户端可以处理什么样的数据(定义服务器返回格式)。

这些类型统称为MIME类型,分为两级:类型和子类型。例如:application/json

text/*
image/*
application/*
...等

当然也可以自定义非标准的定制类型和子类型,只要以x-开头。例如flash文件,使用application/x-shockwave-flash类型。

最后以空行,或者空行+数据体

服务端响应如下

java 复制代码
HTTP/1.1 200 OK                          # 状态行(协议版本 + 状态码 + 原因短语)
Server: nginx/1.18.0                     # 服务器软件及版本
Date: Fri, 13 Oct 2023 05:30:15 GMT      # 响应生成时间
Content-Type: text/html; charset=UTF-8   # 消息体的格式和编码
Content-Length: 1234                     # 消息体的字节长度
Connection: keep-alive                   # 连接控制(保持活跃)
Cache-Control: max-age=3600              # 缓存策略(有效期1小时)
ETag: "abc123xyz"                        # 资源版本标识符
Last-Modified: Mon, 09 Oct 2023 12:00:00 GMT  # 资源最后修改时间

<!DOCTYPE html>                          # 空行(分隔首部和消息体)
<html>                                   # 消息体(实际返回的内容)
  <head><title>Example Page</title></head>
  <body><h1>Hello World</h1></body>
</html>

第一行表示服务器使用的协议HTTP1.1,紧跟一个响应码。其他首部行则指出请求的日期、消息体字节长度等

2.Keep-Alive

在HTTP请求的首部中大家是否注意到Keep-Alive,他表示可以重用一个socket:

Connection:Keep-Alice。

在HTTP1.0会为每个请求打开一个新的连接,而这样打开和关闭消耗的资源远远大于实际传输数据的开销。所以在HTTP1.1以后就默认支持,复用socket连接,如果需要关闭则使用上述key-value显示控制。

  • 在java中可以通过http.keepAlive控制true/false,来控制socket复用
  • http.maxConnections可以表示希望同时打开的socket的数量,来保证服务器不会被大量连接冲崩溃。

HTTP方法

HTTP服务器的遵循请求-响应模式:无状态请求+无状态响应。

HTTP的方法主要有4个:

POST、GET、PUT、DELETE

对于这些方法的使用,再谈谈几点容易被忽略的细节:

  • GET方法获取一个资源,它没有副作用,如果失败可以反复执行,而不用担心有什么问题
  • GET输出可能会被缓存,可以通过首部取消缓存进行禁用
  • PUT方法表示将资源上传到服务器,但它具有幂等性。重复该方法也不用担心是否失败,两次将同一个文档放在同一个位置并不影响。
  • DELETE与PUT一样具有幂等性,重复执行,也只会将资源删除一次。
  • POST是最常用的方法,POST要用于不能重复的不安全的操作,如完成一个交易。

很多网站使用一些小文本串 在连接之间存储持久的客户端状态 ,这些称为cookie。

cookie在请求和响应的HTTP首部中,由服务器传递到客户端,再从客户端传回服务器。

cookie可以是标识会话ID、购物车、登录凭据等信息,也可以存无意义的值。

要在浏览器设置一个cookie,则需要服务器端在响应中使用Set-Cookie首部行:

java 复制代码
HTTP/1.1 200 OK                          # 状态行(协议版本 + 状态码 + 原因短语)
Content-Type: text/html; charset=UTF-8   # 消息体的格式和编码
Set-Cookie: xxx=dsahjfkeqyowqlf   # 设置cookie

而后,客户端再向同一个服务发送请求:

java 复制代码
GET /index.html HTTP/1.1          # 请求行(方法 + URI + HTTP版本)
Host: www.example.com            # 目标主机(必需首部)
Cookie:cart = dsahjfkeqyowqlf   #cookie要与服务器给的一致

当然服务器可以设置不止一个cookie,可以有多个Set-Cookie,用于控制过期时间、路径、端口、值等信息。

默认情况下,cookie来自哪个服务器则应用于哪个服务器。网站也可以指示一个cookie用于整个子域,例如从www.foo.example.com响应的:

Set-Cookie:user = elharo;Domain=.foo.example.com

表示浏览器除了可以用cookie返回最初的www.foo.example.com,还可发送给*.foo.example.com

当然还可以缩小它的使用域

例如:Set-Cookie: user=elharo; Path=/restricted,表示请求服务器上子树/restricted,可以。而相同网站的其他目录中就不能使用这个cookie。

在Set-Cookie中使用expires = Wdy, DD-Mon-YYYY HH:MM:SS GMT 可以设置cookie的过期时间。

设置Max-Age = 3600 ,则表示3600秒后过期,此时浏览器会从缓存中删除这些cookie。


总结

本章节介绍了HTTP协议是现代Web通信的核心,其设计简洁高效,支持多种请求方法和数据格式,并通过Cookie机制实现了客户端状态的持久化。随着HTTP版本的演进,连接复用等优化机制进一步提升了通信性能。本文详细介绍了HTTP协议的基本原理、请求响应格式、方法特性以及Cookie机制。

相关推荐
郑州吴彦祖7725 分钟前
《深入解析Java synchronized死锁:从可重入锁到哲学家就餐问题》
java·线程·synchronized
Seven979 分钟前
【设计模式】命令模式助力快速添加新命令而不影响现有代码
java·后端·设计模式
计算机-秋大田11 分钟前
基于SpringBoot的餐厅点餐管理系统设计与实现(源码+SQL脚本+LW+部署讲解等)
java·vue.js·spring boot·后端·课程设计
好多大米16 分钟前
2.JVM-通俗易懂理解类加载过程
java·jvm·spring·spring cloud·tomcat·maven·intellij-idea
青云交17 分钟前
Java 大视界 -- 基于 Java 的大数据分布式数据库架构设计与实践(125)
java·大数据·分布式·分布式数据库·架构设计·数据处理·高可用性
跪在镜子前喊帅18 分钟前
【面试】JVM
java·面试
茂茂在长安23 分钟前
JAVA面试_进阶部分_java中四种引用类型(对象的强、软、弱和虚引用)
java·jvm·面试
程序员鱼皮25 分钟前
带大家做了个 AI 项目,没想到这么简单!
java·程序员·ai 编程
北京_宏哥36 分钟前
《手把手教你》系列基础篇(九十七)-java+ selenium自动化测试-框架设计篇-Selenium方法的二次封装和页面基类(详解教程)
java·selenium·前端工程化