简述HTTP协议

栏目: 后端 · 前端 · 发布时间: 5年前

内容简介:身为开发人员除了应该对我们所写的项目需求要了解,以及基本的语言知识,对于

身为开发人员除了应该对我们所写的项目需求要了解,以及基本的语言知识,对于 HTTP 协议应该也是应该了解一下的,因为这些东西与我们是密不可分的,每天都在和 HTTP 打交道然而却不知道它到底是什么?这样说出去是不是很可悲?简直可歌可泣有没有...

http协议 :HTTP是一个简单的请求-响应协议,它通常运行在TCP之上。它指定了客户端可能发送给服务器什么样的消息以及得到什么样的响应。请求和响应消息的头以ASCII码形式给出;而消息内容则具有一个类似MIME的格式。这个简单模型是早期Web成功的有功之臣,因为它使得开发和部署是那么的直截了当。超文本传输协议( HTTP )是用于传输诸如 HTML 的超媒体文档的应用层协议。它被设计用于 Web 浏览器和 Web 服务器之间的通信,但它也可以用于其他目的。 HTTP 遵循经典的客户端-服务端模型,客户端打开一个连接以发出请求,然后等待它收到服务器端响应。 -- 百度百科

HTTP 是无状态协议,意味着服务器不会在两个请求之间保留任何数据(状态)。在同一个连接中,两个执行成功的请求之间是没有关系的。这就带来了一个问题,用户没有办法在同一个网站中进行连续的交互,比如在一个电商网站里,用户把某个商品加入到购物车,切换一个页面后再次添加了商品,这两次添加商品的请求之间没有关联,浏览器无法知道用户最终选择了哪些商品。而使用 HTTP 的头部扩展, HTTP Cookies 就可以解决这个问题。把 Cookies 添加到头部中,创建一个会话让每次请求都能共享相同的上下文信息,达成相同的状态。通过上述得出结论, http 特点是:无状态,无连接,简单快速。

HTTP交互流程

一个连接是由传输层来控制的,这从根本上不属于 HTTP 的范围。 HTTP 并不需要其底层的传输层协议是面向连接的,只需要它是可靠的,或不丢失消息的(至少返回错误)。在互联网中,有两个最常用的传输层协议: TCP 是可靠的,而 UDP 不是。因此, HTTP 依赖于面向连接的 TCP 进行消息传递,但连接并不是必须的。

  • TCP:面向连接(如打电话要先拨号建立连接)
  • UDP:是无连接的,即发送数据之前不需要建立连接

关于 TCPUDP 这里不做多余赘述,如果想要深入了解两者之间的优缺点以及区别的话,有时间再详细的介绍一下。

其实 HTTP 交互流程就是基于 TCP 连接进行消息传递的,然而这个连接可有可无,具体交互流程如下图:

简述HTTP协议

结合上图详细说明经历的过程:

  1. 打开一个TCP连接:TCP连接被用来发送一条或多条请求,以及接受响应消息。客户端可能打开一条新的连接,或重用一个已经存在的连接,或者也可能开几个新的TCP连接连向服务端
  2. 发送一个HTTP报文:HTTP报文(在HTTP/2之前)是语义可读的。在HTTP/2中,这些简单的消息被封装在了帧中,这使得报文不能被直接读取,但是原理仍是相同的
  3. 读取服务端返回的报文信息,服务器端接收到请求后,进行处理,然后将处理结果响应客户端(HTTP协议)
  4. 关闭连接或者为后续请求重用连接,关闭客户端和服务器端的连接(HTTP1.1后不会立即关闭)

HTTP 流水线启动时,后续请求都可以不用等待第一个请求的成功响应就被发送。然而 HTTP 流水线已被证明很难在现有的网络中实现,因为现有网络中有很多老旧的软件与现代版本的软件共存。因此, HTTP 流水线已被在有多请求下表现得更稳健的 HTTP/2 的帧所取代。

HTTP报文

Linux 系统下有一个 curl 指令可以通过这个命令来观测一下 HTTP 的请求过程。

curl -v https://segmentfault.com/

输入完之后回车就会看到下面这些信息:

简述HTTP协议

图中 > 开始的是客服端发送给服务端的信息,以 < 开始的为服务端返回给客户端的一些信息。当客户端发起一个 Ajax 请求时,浏览器会携带一些信息发送给服务端, HTTP 请求头提供了关于请求,响应或者其他的发送实体的信息。请求报文分为以下几个部分:

  1. General(请求行)
  2. Response Headers(请求头)
  3. Request Headers(响应头)

这三个部分分别承载了服务端以及客户端所需要的信息,在浏览器中种 NetWork 中可以查看到其信息内容,接下来就一一介绍一下:

General

这部分主要提供的是一些公用的请求头信息:

Request URL: https://segmentfault.com/search?q=search
Request Method: GET
Status Code: 200 
Remote Address: 112.126.83.219:443
Referrer Policy: no-referrer-when-downgrade
  • Request URL:请求地址
  • Request Method:请求方式
  • Status Code:状态码
  • Remote Address:请求的远程地址
  • Referrer Policy: 过滤 Referrer 报头内容

上述信息表明,客户端向服务器发送一个 http 请求,其请求地址为 https://segmentfault.com/search?q=search ,使用 GET 方式发起这个请求,请求返回状态为 200 ,连接的远程地址为 112.126.83.219:443 ,过滤报头采用的是不传递 Referrer

向前面几个应该都比较熟悉也通俗易懂,当看到的这的时候心里有一些些的小疑惑 Remote Address 是什么? Referrer Policy 过滤报头的规则有哪些?

Remote Address

关于 Remote Address 远程连接地址, Remote Address 代表客户端的 IP ,但它的值不是由客户端提供的,而是服务端根据客户端的 IP 指定的,当你的浏览器访问某个网站时,假设中间没有任何代理,那么网站的 web 服务器( Nginx,Apache 等)就会把 Remote Address 设为你的机器IP,如果你用了某个代理,那么你的浏览器会先访问这个代理,然后再由这个代理转发到网站,这样web服务器就会把 Remote Address 设为这台代理机器的 IP 。以至于后面的 443 端口,也简单的看了一下, 443 端口即网页浏览端口,主要是用于 HTTPS 服务,是提供加密和通过安全端口传输的另一种 HTTP 。在一些对安全性要求较高的网站,比如银行、证券、购物等,都采用 HTTPS 服务,这样在这些网站上的交换信息,其他人抓包获取到的是加密数据,保证了交易的安全性。我也没有做深入的了解,大概就是这个样子吧。

Referrer Policy

Referrer-Policy 的作用就是为了控制请求头中 referrer 的内容,目前是一个候选标准,不过已经有部分浏览器支持该标准。目前 Referrer-Policy 只包含以下几种值:

解释
no-referrer 不显示referrer的任何信息在请求头中。
no-referrer-when-downgrade 这是默认值。当从https网站跳转到http网站或者请求其资源时(安全降级HTTPS→HTTP),不显示referrer的信息,其他情况(安全同级HTTPS→HTTPS,或者HTTP→HTTP)则在referrer中显示完整的源网站的URL信息。
same-origin 表示浏览器只会显示referrer信息给同源网站,并且是完整的URL信息。所谓同源网站,是协议、域名、端口都相同的网站。
origin 表示浏览器在referrer字段中只显示源网站的源地址(即协议、域名、端口),而不包括完整的路径。
strict-origin 该策略更为安全些,和origin策略相似,只是不允许referrer信息显示在从https网站到http网站的请求中(安全降级)。
origin-when-cross-origin 当发请求给同源网站时,浏览器会在referrer中显示完整的URL信息,发个非同源网站时,则只显示源地址(协议、域名、端口)
strict-origin-when-cross-origin 和origin-when-cross-origin相似,只是不允许referrer信息显示在从https网站到http网站的请求中(安全降级)。
unsaft-url 浏览器总是会将完整的URL信息显示在referrer字段中,无论请求发给任何网站。

Referrer-Policy 值不是固定不变的,而是可是通过程序手动设置,一般都会不会去手动更改除非网页中不存在一些敏感信息,那就默认使用 no-referrer-when-downgrade 。这里就多说了,如果有兴趣的可以调研一下。

Response Headers

这部分存储的是响应头信息,当服务端接受到请求,并处理完成之后需要向客户端做出应答。

cache-control: no-store, no-cache, must-revalidate
content-encoding: gzip
content-type: text/html; charset=UTF-8
date: Fri, 28 Jun 2019 09:32:09 GMT
expires: Thu, 19 Nov 1981 08:52:00 GMT
pragma: no-cache
status: 200
strict-transport-security: max-age=15768000; preload
x-hit: web1
  • cache-control:响应输出到客户端后,服务端通过该报文头告诉客户端如何控制响应内容的缓存
  • content-encoding:文档编码(Encode)方法。只有在解码之后才可以得到Content-Type头指定的内容类型
  • content-type:文档类型
  • date:当前的GMT时间,可以用setDateHeader来设置
  • expires:文档过期时间,文档到期后则不再缓存
  • pragma:设置消息头,(no-cache)强制清除缓存
  • status:服务器响应状态码
  • strict-transport-security:安全功能,它告诉浏览器只能通过HTTPS访问当前资源,而不是HTTP

Request Headers

这部分承载的是请求头的信息,当客户端向服务端发送请求时,需要传递给服务端的信息内容。

:authority: segmentfault.com
:method: GET
:path: /search?q=1
:scheme: https
accept: text/html,application/xhtml+xml,application/xml;
accept-encoding: gzip, deflate, br
accept-language: zh-CN,zh;q=0.9
cookie: e23800c454aa573c0ccb16b52665ac26=1561712973
referer: https://segmentfault.com/
user-agent: Chrome/75.0.3770.100 Safari/537.
  • :authority:请求权限(HTTP2.0)
  • :method:请求方式(HTTP2.0)
  • :path:请求地址(HTTP2.0)
  • :scheme:请求协议(HTTP2.0)
  • accept:指定客户端可以接受的内容类型,比如文本,图片,应用等等,内容的先后 排序 表示客户端接收的先后次序,每种类型之间用逗号隔开。
  • accept-encoding:客户端接收编码类型,一些网络压缩格式:Accept-Encoding: gzip, deflate, sdch。相对来说,deflate是一种过时的压缩格式,现在常用的是gzip
  • accept-language:客户端可以接受的语⾔言类型,参数值规范和 accept的很像。一般就接收中文和英文,有其他语言需求自行添加。
  • cookie:同样是一个比较关键的字段,Cookie是 client 请求服务器时,服务器会返回一个键值对样的数据给浏览器,下一次浏览器再访问这个域名下的网页时,就需要携带这些键值对数据在 Cookie中,用来跟踪浏览器用户的访问前后路径。
  • referer:浏览器上次访问的网页url,uri。由于http协议的无记忆性,服务器可从这里了解到客户端访问的前后路径,并做一些判断,如果⼀一次访问的 url 不能从前一次访问的页面上跳转获得, 在一定程度上说明了请求头有可能伪造。
  • user-agent:中文名用户代理,服务器从此处知道客户端的操作系统类型和版本,电脑CPU类型,浏览器 种类版本,浏览器渲染引擎,等等。

accept-language 共分为下列几种:

zh-CN:中文简体大陆
zh:其他中文
en-US:英语美语
en:其他英语

Cookie 就是存储在客户端的一小段文本,因为 cookie 是存储在客户端浏览器中的, Cookie 不能作为代码执行,也不会传送病毒,且为你所专有,并只能由提供它的服务器来读取。保存的信息片断以 名/值 对( name-value )的形式储存,一个 名/值 对仅仅是一条命名的数据。一个网站只能取得它放在你的电脑中的信息,它无法从其它的 cookie 文件中取得信息,也无法得到你的电脑上的其它任何东西。

const express = require('express');
const cookieParser = require('cookie-parser');
var app = express();
app.use(cookieParser('sign'));
app.get('/set', function(req, res) {
    res.cookie('name', 'TracyYu', {maxAge: 9999999, httpOnly: true, signed: true});
    res.send('cookie设置成功');
})
app.get('/get', function(req, res) {
    console.log(req.signedCookies);
    res.send('success')
})
app.listen('3000', function() {
    console.log('3000成功');
})

通过上面代码中对 cookie 进行设置之后,用户访问 /set 路由的是时候已经把 cookie 设置到了浏览器的头部,当用户访问 /get 路由的时候,由于在浏览器中已经设置好 cookie ,在同属于一个服务的情况下是可以直接获取到 cookie 的。当然除了上述所说,通过 document 也是可以手动设置 cookie 的,在客户端设置的 cookie 在服务端同样是也可以获取到的。

document.cookie="userId=929";

这样就将名为 userIdcookie 值设置为了 929 ,现在访问 /get 同样就能拿到在客户端设置的 cookie 值了。

请求方式

http 中经常用的到的就是 getpost 两种,在开发过程中会遵循 RESTful 接口风格,这是一种现在比较流行的接口风格,使用这种接口风格需要用到一些其他的请求方式, http 请求方式一共有 8 种。

请求方式 描述
OPTIONS 允许客户端查看服务器的性能,服务器针对特定资源所支持的HTTP请求方法,也可以利用向web服务器发送‘*’的请求来测试服务器的功能性
HEAD 向服务器索与GET请求相一致的响应,只不过响应体将不会被返回。这一方法可以再不必传输整个响应内容的情况下,就可以获取包含在响应小消息头中的元信息。
GET 向特定的资源发出请求。它本质就是发送一个请求来取得服务器上的某一资源。资源通过一组HTTP头和呈现数据(如HTML文本,或者图片或者视频等)返回给客户端。GET请求中,永远不会包含呈现数据。
POST 向指定资源提交数据进行处理请求(例如提交表单或者上传文件)。数据被包含在请求体中。POST请求可能会导致新的资源的建立和/或已有资源的修改。
PUT 向指定资源位置上传其最新内容
DELETE 请求服务器删除Request-URL所标识的资源
TRACE 回显服务器收到的请求,主要用于测试或诊断
CONNECT HTTP/1.1协议中预留给能够将连接改为管道方式的代理服务器。

HTTP 定义了与服务器交互的不同方法,最基本的方法是 GETPOST (开发关心的只有 GET 请求和 POST 请求)。

GET和POST长度的限制问题

GET POST
GET是通过URL提交数据,因此GET可提交的数据量就跟URL所能达到的最大长度有直接关系 HTTP协议没有对POST进行任何限制,一般是受服务器配置限制或者内存大小
HTTP协议对URL长度是没有限制的;限制URL长度大多数是浏览器或者服务器的配置参数 PHP下可以修改php.conf的postmaxsize来设置POST的大小

其实这里有一个很大的误区, http 协议并未规定 GETPOST 的长度限制, GET 的最大长度限制是因为浏览器和 web 服务器限制了 URL 的长度,不同的浏览器和 web 服务器,限制的最大长度不一样,要支持 IE ,则最大长度为 2083byte ,若支持 Chrome ,则最大长度 8182byte ,首先即使 GET 有长度限制,也是限制的整个 URL 的长度,而不仅仅是参数值数据长度。

GET和POST的安全性

  1. GET是通过URL方式请求,可以直接看到,明文传输
  2. POST是通过请求header请求,可以开发者 工具 或者抓包可以看到,同样也是明文的
  3. GET请求会保存在浏览器历史纪录中,还可能会保存在Web的日志中

GET 请求指定资源的表示形式。注意, GET 不应该用于产生副作用的操作,比如在 web 应用程序中使用它执行操作。原因之一是 GET 可能被机器人或爬行器任意使用,它们不需要考虑请求应该引起的副作用。 POST 将要处理的数据(例如,从 HTML 表单)提交给标识的资源。数据包含在请求体中。这可能会导致创建新资源或更新现有资源,或者两者兼而有之。使用 HTTP 协议的服务不应该使用基于 GET 的表单来提交敏感数据,因为这会导致这些数据在 Request-URI 中编码。许多现有服务器,代理和用户代理会将请求 URI 记录在第三方可能看到的某个位置。服务器可以使用基于 POST 的表单提交。

GET与POST请求过程

POST 请求的过程:

  1. 浏览器请求tcp连接(第一次握手)
  2. 服务器答应进行tcp连接(第二次握手)
  3. 浏览器确认,并发送post请求头(第三次握手,这个报文比较小,所以http会在此时进行第一次数据发送)
  4. 服务器返回100 Continue响应
  5. 浏览器发送数据
  6. 服务器返回200 OK响应

GET 请求的过程:

  1. 浏览器请求tcp连接(第一次握手)
  2. 服务器答应进行tcp连接(第二次握手)
  3. 浏览器确认,并发送get请求头和数据(第三次握手,这个报文比较小,所以http会在此时进行第一次数据发送)
  4. 服务器返回200OK响应

总结

原本想说一写状态码相关的东西,但是简单的看了一下,好像又没有什么好说的,百度百科说的也很清楚,就不在文章里面赘述了。

简单的对 http 协议做了一些小的介绍与总结,如果文章中有哪些地方有问题,请在下方留言指正,我会尽快做出改正。


以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

深入浅出Ajax

深入浅出Ajax

(美)Brett McLaughlin / 东南大学出版社 / 2006-5 / 98.00元

本书将教会您如何在很短的时间内掌握使用JavaScript代码来向服务器提交异步请求?同时,您可以学习如何使用诸如动态HTML、XML、JSON、DOM等技术来解决开发过程中遇到的许多问题。让你从那些繁琐而笨拙的网站开发技术中彻底解放出来!本书将是一本指导您进行异步开发的经典参考书籍。   作为一名网站设计人员,您也许时常因为遇到以下情况而烦恼:用户只是移动了鼠标就要从服务器重载数据......一起来看看 《深入浅出Ajax》 这本书的介绍吧!

RGB转16进制工具
RGB转16进制工具

RGB HEX 互转工具

Base64 编码/解码
Base64 编码/解码

Base64 编码/解码

SHA 加密
SHA 加密

SHA 加密工具