详解HTTP协议(一)

1、HTTP概述

1、什么是HTTP

超文本传输协议(Hyper Text Transfer Protocol,HTTP)

HTTP是一个基于请求与响应的、无状态的应用层协议,用于在两点之间传输超文本数据,常基于TCP/IP协议传输数据

设计HTTP的初衷是为了提供一种发布和接收HTML页面的方法

2、HTTP的特点

  • 基于TCP/IP协议:连接可以保证安全可靠,但内容就无法保证安全隐私了。
  • 基于请求响应模型:一次请求对应一次响应
  • 无状态的:每次请求之间相互独立

3、HTTP的优缺点

优点:

  • 简单:HTTP的报文格式是header+body,头部信息也是简单的key-value形式,易于解析
  • 灵活且易于扩展:HTTP工作在应用层,下层可以随意变化。而且HTTP的请求方法、状态码、头字段等组成部分都可以自定义,即插即用
  • 应用广泛且跨平台

缺点,都属于双刃剑:

  • 无状态:
    • 好处:服务器不需要保存每个HTTP连接的状态,减轻服务器的压力,把资源都用于提供服务
    • 坏处:完成有关联性的操作时比较麻烦,可以用Cookie、Session解决,手动维护状态
  • 明文传输
    • 好处:方便解析、调试
    • 坏处:容易被他人获取请求或响应的内容,不安全

HTTP最大的缺点就是不安全,体现在:

  • 通信使用明文,不加密,内容可能被窃取
  • 不会对通信双方的身份进行验证,可能访问到伪装的站点
  • 无法验证报文的完整性、正确性,通信内容可能被篡改

HTTP的安全问题,在HTTPS上得到了解决,引入了SSL/TSL层,获得了极致的安全。

4、为什么有了TCP还需要HTTP

  • 分层结构,TCP负责端到端的传输,HTTP专注于应用层的逻辑。上层服务不应该去强耦合底层协议,协议是会升级和淘汰的
  • TCP已经负责了很多事情,再给它加字段加功能会导致TCP过于庞大,难以升级和维护
  • 直接面向TCP开发网络应用,不利于专注于业务的开发,可能会深陷于协议的细节中

2、HTTP请求

1、HTTP请求报文组成

HTTP请求报文由4部分组成(请求行+请求头+请求空行+请求体

下面是一个POST方法的请求报文:

1、请求行

请求行分为三个部分:请求方法、请求地址URL和HTTP协议版本,它们之间用空格分割。例如,GET /index.html HTTP/1.1。

1、请求方法

HTTP/1.1 定义的请求方法有8种:

最常用的两种是GETPOST

2、URL

URI:统一资源标识符,在网络上唯一标识一个资源

URL:统一资源定位符,是一种资源位置的抽象唯一识别方法。

组成:<协议>://<主机>:<端口>/<路径>

端口和路径有时可以省略(HTTP默认端口号是80)

URL是URI的子集,它不仅唯一标识的一个资源,还提供了对该资源的访问方式。 

3、协议版本

协议版本的格式为:HTTP/主版本号.次版本号,常用的有HTTP/1.0和HTTP/1.1、HTTP/2、HTTP/3

2、请求头

请求头部为请求报文添加了一些附加信息,由键值对组成,每行一对,名和值之间使用冒号分隔。

3、请求空行

请求头部的最后会有一个空行,表示请求头部结束,接下来为请求数据。

4、请求体

请求数据不在GET方法中使用,而在POST方法中使用。POST方法适用于需要客户填写表单的场合

与请求数据相关的最常使用的请求头部是Content-Type和Content-Length。

2、GET与POST

1、两者的区别

GET

  • GET的含义是,从服务器获取指定的资源,要求服务器将目标资源放在响应报文的数据部分发送给客户端。

  • GET方式的请求不包含请求体部分,在URL后面使用一个问号分隔,然后把请求参数和对应的值直接附加在后面,这种方式的弊端是:

    • 参数长度受限制,不能传送大量数据
    • 不适合传送私密数据
  • GET也可以有请求体,但是RFC定义GET的作用是请求资源,所以根据这个语义,GET不需要请求体。

POST

  • POST的含义是,根据请求体的内容,对服务器的指定资源做相应的处理。
  • 将请求参数以键值对的形式封装在请求体中,好处是:
    • 浏览器不会对请求体大小做限制,可以传输大量数据
    • 数据不会直接展示在URL中,相对安全一些。但是HTTP是明文传输,抓个包就能看到了。
  • POST的URL也是可以带参数的,但一般没人这么做

2、它们是安全与幂等性吗

安全:请求不会破坏服务器的资源

幂等:多次发起相同的请求,返回结果都是相同的

结论:

  • 请求本身不能体现什么,得看它们具体做了什么事情。

  • GET方法一般用来读数据,是只读的,所以安全、幂等。

    • 所以可以给GET请求的响应做缓存,可以把响应的内容缓存在浏览器,也可以缓存在代理服务器
  • POST一般用来新增或修改数据,所以不安全、不幂等

    • 所以浏览器一般不会缓存POST请求的响应
  • 但是实际开发中,可以用GET请求来完成数据的修改和删除,也可以用POST来完成数据的查询

    那么此时GET就是不安全不幂等的,POST就是安全幂等的,所以还是要根据实际使用来确定。

3、HTTP响应

1、什么是响应

响应内容是服务器返回给浏览器的内容

当服务器收到浏览器的请求后,会发送响应消息给浏览器,浏览器根据响应内容来作出显示。

2、响应报文格式

HTTP响应与HTTP请求相似,也由4个部分构成:

  1. 响应行
  2. 响应头
  3. 响应空行
  4. 响应体

看一个简单的响应报文:

响应行:

HTTP/1.1 200 OK

响应头:

Server: Apache-Coyote/1.1

Content-Type: text/html;charset=UTF-8

Content-Length: 624

Date: Mon, 03 Nov 2014 06:37:28 GMT

响应空行

响应体

解析:

响应行:

  • HTTP/1.1 200 OK:响应协议为HTTP1.1,状态码为200,表示请求成功,OK是对状态码的解释;

响应头:

  • Server: Apache-Coyote/1.1:服务器的版本信息;
  • Content-Type: text/html;charset=UTF-8:响应体是html文件,使用的编码为UTF-8;
  • Content-Length: 624:响应体为724字节;
  • Set-Cookie: JSESSIONID=C97E2B4C55553EAB46079A4F263435A4; Path=/hello:响应给客户端的Cookie;
  • Date: Mon, 03 Nov 2014 06:37:28 GMT:响应的时间,这可能会有8小时的时区差;

响应空行:

  • 和请求空行一样,用途是分隔响应头和响应体。

响应体:

  • 响应体有时是一个html文件,浏览器可以直接访问。
  • 如果访问的是一个jsp页面,响应返回的也是一个html文件。服务器将该jsp翻译成了一个html,然后再响应给浏览器。
  • 响应体的类型,由响应头的Content-Type指出

3、HTTP的常见字段

1、请求字段

  • Host:客户端发送请求时,用来指定服务器的域名。
  • Accept:客户端告诉服务器,自己接收什么格式的数据
    • Accept: */* ,代表任何格式都可以
  • Accept-Encoding:客户端告诉服务器自己支持的压缩方式
    • Accept-Encoding: gzip, deflate
  • User-Agent:客户端告诉服务器,自己的浏览器信息
  • Referer:客户端告诉服务器,当前请求的来源地址,可以做防盗链或统计工作
  • Connection:使用TCP长连接

2、响应字段

  • Content-Type:服务器告诉客户端,本次响应的格式
    • Content-Type: text/html; charset=utf-8
  • Content-Length:本次响应的字节长度
    • Content-Length: 1000
  • Content-Encoding:指定服务器返回的数据的压缩方式
    • Content-Encoding: gzip
  • Connection:使用TCP长连接
    • Connection: keep-alive
  • Set-Cookie:服务器发给客户端的Cookie

3、响应行的状态码

响应状态码由三位数字组成,表示服务器对请求的响应结果

相当于服务器和浏览器单方面的暗号,浏览器接收到这三位数字,就明白了服务器的含义。

HTTP响应状态码的第一个数字定义了响应的类别,后面两位没有具体分类,第一个数字有五种可能的取值,具体介绍如下所示:

分类 分类描述
1xx 提示信息,服务器收到了请求,但需要客户端继续执行操作
2xx 成功,报文被成功接收并处理
3xx 重定向,资源位置发生变动,需要客户端重新发送请求
4xx 客户端发生错误,发来的请求报文有误,服务器无法处理。
5xx 服务器发生错误,服务器在处理请求的过程中发生了错误

常用的具体状态码如下:

状态码 含义
200 请求成功,浏览器会把响应回来的信息显示在浏览器端。
302 表示重定向。比如说浏览器访问一个资源,服务器响应给浏览器一个302的状态码,并且通过响应头Location发送了一个新的url,告诉浏览器去请求这个url。这就是重定向。
304 第一访问一个资源后,浏览器会将该资源缓存到本地,第二次再访问该资源时,如果该资源没有发生改变,那么服务器响应给浏览器304状态码,告诉浏览器使用本地缓存的资源
404 客户端错误的一种,比如说在浏览器端请求一个不存在的资源,这时浏览器端会出现404状态码。
405 客户端错误的一种,表示当前的请求方式不支持。比如说服务器端只对GET请求做了处理,而客户端的请求是post方式的,这个时候会出现405状态码。
500 服务器端错误,比如说服务器端代码出现空指针等异常,浏览器就会收到服务器发送的500状态码。

300系列详解

  • 301:永久移动,服务器自动将请求转到新的地址
  • 302:重定向,服务器返回浏览器一个新的地址,浏览器再次访问这个地址去获得数据
  • 304:服务器告诉浏览器资源未修改,使用本地缓存

4、响应头

格式:

  • 响应头名称:值
  • 例如,Server : Apache-Coyote/1.1

常用的响应头:

响应头名称 含义
Content-Type 服务器告诉客户端,本次响应体的数据格式以及编码格式(字符集)
Content-Disposition 服务器告诉客户端,以什么格式打开响应体数据。

详解:

  • Content-Disposition
    • 默认值为in-line,在当前页面打开。
    • 也可以设置为attachment,以附件形式打开响应体,用于文件下载。

5、响应体

响应体就是传输的数据。

4、资源跳转的不同方式

请求转发(forward)、请求重定向(redirect)、定时刷新都可以实现资源的跳转,但它们有一些区别。

1、资源跳转方式的区别

  • 请求转发

    • 一次请求,一次响应

    • 地址栏不变

    • 只能在服务器内部同一应用跳转,不能转发到别的服务器

  • 请求重定向

    • 两次请求,两次响应,不同的request对象(每次请求服务器都会创建新的request对象)

    • 地址栏发生了改变

    • 既可以在服务器内,也可以不同服务器不同应用上跳转

  • 定时刷新

    • 两次请求,两次响应,不同的request对象
    • 地址栏发生了改变
    • 可以用于服务器内部的资源跳转,也可以用于不同应用和不同服务器之间的资源跳转
    • 定时刷新和请求重定向的区别是,定时刷新可以设置时间间隔,比如实现“登录成功,5秒后返回首页”的操作。

2、资源跳转方式的实现过程

一句话总结:转发是服务器行为,重定向是客户端行为。为什么这样说呢,这就要看两个动作的工作流程:

转发过程:

  1. 客户浏览器发送http请求
  2. web服务器接受此请求
  3. 服务器调用内部的一个方法在容器内部完成请求处理和转发动作
  4. 将目标资源发送给客户

在客户浏览器路径栏显示的仍然是其第一次访问的路径,也就是说客户是感觉不到服务器做了转发的。

转发行为是浏览器只做了一次访问请求。

重定向过程:

  1. 客户浏览器发送http请求
  2. web服务器接受后发送302状态码,以及对应新的location给客户浏览器
  3. 客户浏览器发现是302响应,则自动再发送一个新的http请求,请求url是新的location地址
  4. 服务器根据此请求寻找资源并发送给客户端

既然是浏览器重新发出了请求,则就没有什么request传递的概念了。

在客户浏览器路径栏显示的是其重定向的路径,客户可以观察到地址的变化的。

重定向行为中,浏览器做了至少两次的访问请求。

在重定向的过程中,传输的信息会被丢失

3、转发和重定向的功能区别

转发:客户端提交了请求,服务器根据内部逻辑,跳转多个地址,给客户端返回最终结果。

重定向:客户端提交了请求,服务器返回302状态码和新的地址,要求客户端再次发出请求,客户端请求新的地址后,服务器返回最终结果。

简单来说,转发属于服务器内部的事情,比如一件事情A做了一半,发送给B继续做,最后完成。对于客户端而言,它只知道自己最早请求的那个A,而不知道中间的B,甚至C、D。

而重定向是,请求发送给A,A判断这件事无法完成,要求客户端再去访问B,B发现可以做,就完成了。这个时候浏览器可以看到地址变了,而且历史的回退按钮也亮了。重定向可以访问自己web应用以外的资源。

生活中的例子:

假设你去办理某个执照,

转发:你先去了A局,A局看了以后,知道这个事情其实应该B局来管,但是他没有把你退回来,而是让你坐一会儿,自己到后面办公室联系了B的人,让他们办好后,送了过来。

重定向:你先去了A局,A局的人说:“这个事情不归我们管,去B局”,然后,你就从A退了出来,自己乘车去了B局。

猜你喜欢

转载自blog.csdn.net/m0_62609939/article/details/131852714
今日推荐