HTTP背后的故事:理解现代网络如何工作的关键(二)

一.认识请求方法(method)

1.GET方法

请求体中的首行包括:方法,URL,版本号

方法描述的是这次请求,是具体去做什么

GET方法:

1.GET 是最常用的 HTTP 方法. 常用于获取服务器上的某个资源。

2.在浏览器中直接输入 URL, 此时浏览器就会发送出一个 GET 请求.
另外, HTML 中的 link, img, script 等标签, 也会触发 GET 请求.

GET 请求的特点
  • 首行的第一部分为 GET
  • URL query string 可以为空, 也可以不为空.
  • header 部分有若干个键值对结构.
  • body 部分为空.

2.POST方法

POST 方法也是一种常见的方法, 多用于提交用户输入的数据给服务器(例如登陆页面).

通过 HTML 中的 form 标签可以构造 POST 请求, 或者使用 JavaScript ajax 也可以构造 POST 请求.

两个非常经典使用POST场景
1.登录

2.上传

登录码云时

POST 请求的特点
  • 首行的第一部分为 POST
  • URL query string 一般为空 (也可以不为空)
  • header 部分有若干个键值对结构.
  • body 部分一般不为空. body 内的数据格式通过 header 中的 Content-Type 指定. body 的长度由
  • header 中的 Content-Length 指定.


 3.GET和POST

 我们知道请求体的基本格式包含四个部分:首行,请求头(Header),正文(Body),空行

在正文body中,body是你可以存放任意格式的数据,只有前端和后端约定好即可,从使用习惯上说,GET没有body,POST含有body,GET会把需要给服务器的补充信息放到query string中(url)

POST会把这些信息放到body中。

对于GET和POST在使用习惯上还是有明显区别的

1.GET习惯于把数据放到url中的query string中,POST习惯于把数据放到body中。

GET也可以把数据放到body中,POST也可以把数据放到query string,大部分服务器和浏览器都适用,注意我说的是大部分。 

2.语义上的区别,在标准文档中,GET的语义是用来获取数据,POST的语义是给服务器传输数据

但实际使用不一定拘泥于上述要求 

3.关于幂等性,在标准文档中,建议GET请求实现成幂等的,POST则无要求。

什么是幂等?

1.每次输入的内容一定,输出的结果也一定,称之为幂等。

2. 每次输入的内容一定,输出的结果不一定,不是为幂等。

GET在实际开发中也可以不实现幂等

4.GET请求是可以被浏览器收藏夹收藏的,POSt请求不可以。


网上的以下说法不太准确,这里做些补充。

1.POST比GET更安全,因为在登录时,如果使用GET,用户名密码就会显示url中,此时会被别人看见,显得不安全。

但其实是POST,数据没有显示在url中,也是可以被黑客通过抓包获取到的,真正保证安全性关键在于加密,如果数据加密了,就算放到url显示又如何呢?

2.GET传输的数据量小(存在上限),POST传输的数据量更大

这描述的是在以前,实际上HTTP标准文档上明确说了,对于GET,url的长度不受限制,之前老版本的IE浏览器在实现的时候,url长度确实是有限制,不过这是放在以前,现在比较长的url也是很常见的

3.GET 只能携带文本数据,POST 则可以携带二进制数据

这个说法不能说是完全错误,确实有一定的局限性的.
URL 通过 query string 来携带数据
query string 是只能包含文本的. 但是可以对二进制数据进行 urlencode(转码),自然就成了文本了
到了服务器自然进行 urldecode(解码), 就能把数据还原成二进制.
POST 请求 body 中也经常不是直接携带二进制
也有很多时候是对二进制数据进行 urlencode/ base64 等方式进行转码

 4.其他方法

实际上,这些方法的语义是属于标准文档作者的制定原则,Http 是应用层协议,开发者在实际开发时,完全可以自己制定“规则”,如上可以在POST来从服务器拿数据,也可以用GET往服务器放数据。甚至可以全用POST。

其他方法

  • PUT POST 相似,只是具有幂等特性,一般用于更新
  • DELETE 删除服务器指定资源
  • OPTIONS 返回服务器所支持的请求方法
  • HEAD 类似于GET,只不过响应体不返回,只返回响应头
  • TRACE 回显服务器端收到的请求,测试的时候会用到这个
  • CONNECT 预留,暂无使用
  • 这些方法的 HTTP 请求可以使用 ajax 来构造. (也可以通过一些第三方工具)

以上用法比较少,绝大部分都是使用GET/POST方法


二.认识请求报头(header) 

1.Host

Host :表示服务器主机的地址和端口.
比如

其实URL 已经包含了 Host 了(gitee.com)
这里的 Host 和 URL 中的 ip 地址 端口,绝大部分情况下都是一样的
少数情况可能不同。


2.Content-Length

Content-Length:表示 body 中的数据长度

通过这个长度来处理粘包问题,因为HTTP 底层也是基于 TCP
连续传输多个 HTTP 数据报,此时接收方这边的接收缓冲区里就会积累多个包的数据,应用程序在读取这些数据的时候就需要明确包之间的边界。

3.Content-Type

Content-Type :表示请求的 body 中的数据格式.

 

body 可以传输很多种格式的.包括程序员也可以自己约定任意的格式
但是有些格式是非常常见的,比如

请求中的格式如下:
1. application/json  (body就是json)
2.application/x-www-form-urlencoded(form表单)
3. multipart/form-data (上传文件时使用)

响应中的格式如下:

1. text/plain 纯文本
2. text/html html
3. text/css Css
4. application/javascript js
5. application/json
6. image/png
7. image/jpg


同时响应格式的后面还可以添加编码方式
如:

4 User-Agent(简称UA)  

User-Agent:表示浏览器/操作系统的属性

用法有三点: 

1.UA可以根据当时用户使用的设备来正常的打开网站

在上古时期,上古时期,UA 非常关键的部分.不同用户使用的上网的设备,差异很大,(当年计算机发展速度日新月异),同一个时间段内,用户使用新设备和或者是旧设备的情况的会同时存在,旧设备打开新特性的网站是无法正常打开的。

比如你是一个程序员,你要写一个网站,你写的网站是否要使用新的特性呢?
使用新特性,老的设备就无法正常打开
不使用新特性,你这个网站就打打不过竞争对手。

而借助 UA 就能解决上述问题
服务器就可以针对此时的 UA 的信息进行判定。
如果用户用的是很老的设备,返回的页面就不包含新特性, 确保这个页面能够正确访问出来。
如果用户用的是新的设备,返回的页面就包含新特性,确保这个页面体验足够好。

2.根据操作系统的不同来返回对应的页面布局.

UA 里包含了系统信息,就可以判定系统是 PC 的系统还是移动端的系统,此时就可以根据这个信息来返回不同的页面了

不过现在常用的使用响应式布局来进行页面布局。

因为使用UA的话需要维护两段代码(PC端和移动端)

而响应式布局中通过一套代码,就可以适应不同尺寸的显示器

取值的CSS3 提供了一个特性,"媒体查询"
可以感知到当前屏幕的尺寸,根据不同的尺寸,应用不同的样式。

3. 手动把 UA 改成 PC的 UA,手机版就能访问 电脑版 的网页了。


5.Referer

Referer:描述了当前的页面从哪里来的,

以前refer是可以被修改的,比如我是从百度跳转这个广告,可以修改成来自360跳转。这样会属于百度的流量丢失,等于钱丢失。

所以现在的 HTTP S 就能够很好的解决上述问题。
SSL(网络中用于加密的协议),加密就能把 header 和 body 都进行加密网络上传输的就是密文了,运营商要想修改,就得先破解~~,就算你能解密,你也篡改不了(一旦修改就能被用户的浏览器感知到)。

6.cookie 

 Cookie 本质上是一个,浏览器这边本地持久化存储数据的机制,就是把数据存到硬盘里。

在谈及cookie的作用之前,先看看下面两个问题。 

浏览器作为电脑上的一个程序,能否直接读写本地磁盘文件呢?
当然可以! 系统提供了 API 操作文件作为一个程序当然可以调用这些 api 来操作了~


浏览器上运行的网页,能否通过浏览器提供的 api 来读写本地磁盘文件呢?

可以,理论上完全可行,但是浏览器禁止了这种做法.(浏览器并没有给网页提供这样的 api)
一个网页不能直接的读写你的硬盘文件。这是为了安全性!假如你打开一个网站,随手一点就打开了
一个黑客搞的恶意网站,此时,人家通过网页直接把你电脑上的所有学习资料都给你一删,必然会造成重大损失!!

但是确实,有些网站,是需要把一些信息保存到浏览器这边的,比如当前登录的用户的身份信息.

那怎么办捏,如下

HTTP 请求中的 Cookie 字段, 就是把本地存储的 Cookie 信息发送到服务器这边
HTTP 响应中会有一个 Set-Cookie 字段,就是服务器告诉浏览器你要在本地保存哪些信息

格式都是程序员定义的键值对

Cookie的作用:

通过Cookie,网站可以识别并记住用户的身份和会话状态,如登录状态、购物车内容等。这样,用户在不同页面之间跳转时,网站能够持续提供个性化的服务,如保持用户登录状态、显示用户购物车中的商品等。

象你去了一家你常去的咖啡馆。这家咖啡馆为了提供更好的服务,决定用一种小卡片来记住你的喜好。这就是Cookie在Web世界中的类似物。

  • 第一次去咖啡馆:你告诉服务员你喜欢喝拿铁,不加糖。服务员很贴心地拿出一张小卡片,写上你的偏好,然后把这个小卡片(Cookie)给了你,让你下次来时出示。
  • 下次再去:你走进咖啡馆,直接出示了小卡片(Cookie)。服务员看到你的卡片,立刻就知道你的喜好,直接为你准备了一杯不加糖的拿铁,无需你再次说明。

这里的小卡片就像是Web中的Cookie,它帮助咖啡馆(服务器)记住了你的个人喜好(用户数据)

关于Cookie的重要结论:

1.Cookie 从哪里来?

服务器返回给浏览器的.通常都是首次访问/登录成功之后


2.Cookie 到哪里去?

Cookie 会存储在浏览器本地主机的硬盘上. 后续每次访问服务器都会带上。

Cookie不同的客户端,保存的 Cookie 是不同的.即使是同一个主机,使用不同浏览器,Cookie 大概率也不同。


3.Cookie 中存什么? 键值对格式的数据.这里的内容都是程序员自定义的。和 query string 一样外人无从理解,不同网站的Cookie的都是不一样的


4.Cookie 在浏览器这边如何组织?在硬盘本地保存,是按照不同的域名为维度分别存储,不如你的浏览器访问百度,有一组 cookie 访问搜狗,也有一组 cookie。

5.Cookie用途用来在客户端保存数据,其中最重要的是保存用户的身份标识!!服务器就可以通过标识来区分用户。

一些其他的业务数据一般不会存到cookie中 ,cookie 随时可以删除掉,把业务数据存储在服务器,通过 cookie 中的身份标识找到对应的数据
 

浏览器的另一个保存机制,一般账号密码不会在 cookie 中保存,cookie 是要传输给服务器的

一般浏览器保存的密码都是明文密码,明文密码放到 cookie 当然不合适,虽然有 https 能加密。https 侧重于是"不能被篡改”而不是"不能被解密。

7.补充

  在使用Fiddler抓包时,为什么有一大块呈现灰色?

为什么下面有一整块都是灰色的呢?

因为浏览器和服务器之间要进行多次网络交互,整体的过程是比较低效的,为了提升效率,就会把一些固定不变的内容在浏览器本地的机器硬盘上进行缓存. 例如css,图片,js等,它们是很少发生改变,将这些保存到硬盘上之后,后续再请求,就可以直接从硬盘上读取数据,减少了网络交互的开销.(网络带宽可是比cpu还贵的资源)。

小技巧:使用 ctrl + F5 强制刷新就可以不读取缓存,直接读取服务器数据。

如图

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-07-15 20:48:01       67 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-07-15 20:48:01       71 阅读
  3. 在Django里面运行非项目文件

    2024-07-15 20:48:01       58 阅读
  4. Python语言-面向对象

    2024-07-15 20:48:01       69 阅读

热门阅读

  1. [C++ 基础入门 - inline和 nullptr]

    2024-07-15 20:48:01       17 阅读
  2. STL常用容器及使用总结

    2024-07-15 20:48:01       21 阅读
  3. MiniCPM-V

    MiniCPM-V

    2024-07-15 20:48:01      21 阅读
  4. Mybatis

    Mybatis

    2024-07-15 20:48:01      18 阅读
  5. ORA-12518: TNS: 监听程序无法分发客户机连接

    2024-07-15 20:48:01       14 阅读
  6. 解决PyCharm配置错误:深入剖析与实战指南

    2024-07-15 20:48:01       22 阅读
  7. 关于VUE2在页面离开时,丢弃所有未完成的请求

    2024-07-15 20:48:01       19 阅读
  8. 使用js对文本框设置字数限制

    2024-07-15 20:48:01       20 阅读
  9. Spring boot 2.0 升级到 3.3.1 的相关问题 (一)

    2024-07-15 20:48:01       18 阅读
  10. C++惯用法:do...while(0)的妙用

    2024-07-15 20:48:01       23 阅读