HTTP协议

什么是HTTP

http全称是"超文本传输协议"是一种应用非常广泛的应用层协议。http是基于于TCP协议实现的(http1.0,http1.1,http2.0均以tcp实现,http3.0基于udp实现),目前我们主要使用http1.1和http2.0,本篇文章以http1.1为主。

超文本协议:传输的内容不仅仅是文本(html,css这些是文本)还可以是一些其他资源,如图片,视频,音频等二进制数据。

咱们平时打开一个网站,就是通过http协议传输数据。例如咱们在浏览器输入百度网址http://www.baidu.com,浏览器就该百度的服务器发送一个http请求,百度的服务器返回一个http响应。这个响应被浏览器解析以后,就展示出我们看到的页面。(这个过程中浏览器可能给服务器发送多个http请求,服务器会对应返回多个响应,这些响应中包含了页面html,css,js,图片,字体等信息)

http的报文格式

咱们可以借助抓包工具,如fiddler来分析http协议格式。

  1. http请求,主要由 首行,请求头,空行,正文body组成
    1. 首行:主要有方法,url,版本号三部分
    2. 请求头header:有很多键值对组成,每一行一个键值对,使用:来分割键和值
    3. 空行:header的结束标志
    4. 正文body:承载一些具体的数据,可能是json格式的,也可能是其他格式
  1. http响应,主要由 首行,响应头,空行,正文body组成
    1. 首行:主要由版本号,状态码,状态码分析组成
    2. 响应头header:有多个键值对,每一行一个键值对,使用:来分割键和值
    3. 空行:header的结束标志
    4. 正文body:承载一些具体数据,可能是json格式,也可能是html,css,js,图片等

HTTP请求

认识URL

url就是我们俗称的"网址",是唯一资源定位符(用来找到网络上的资源)。另外一个相近的概念的是uri,唯一资源标识符(用来区分一个网络上的资源)

  • 协议方案名:url并不是http独有的,所以url前头要标识是用哪种协议
  • 登入信息:现在基本没有这个了
  • 服务器地址:就是服务器的ip地址,也可以是域名

域名和Ip地址是等价关系,域名要经过dns解析,帮我们自动把域名转换成Ip地址

  • 服务器端口号:标识要访问目标服务器的哪个进程

ip+port就能确定是互联网上的哪个主机的哪个进程

  • 带层次的文件路径:服务器进程可能会提供出很多资源(比如html文件,css文件,图片等)放到一些具体目录中。咱们就需要指定要访问的路径,才能获得资源。

url中写的路径,不一定完全和服务器上的某个硬盘上的目录一一对应。例如服务器上的目录是D:/source/index.html,把D:/source这个目录映射成http的跟目录/,因此要访问index.html文件,就要写作http://127.0.0.1:80/index.html.

上面index.html是一个真实存在的文件,服务器也可以提供"虚拟出来的文件"。例如,可以在http服务器中,加入一些特殊逻辑,比如请求的url的路径是/test,在http服务器中,直接在内存中构造出一个html,返回给浏览器,此时并没有访问硬盘的真实文件,而是直接在内存中拼一个html出来

  • 查询字符串:?key1=value1&key2=value2查询字符串(query string),浏览器给服务器传递一些必要参数,这些键值对是由业务决定的,完成由程序员自定义。例如http://xxx大学2餐厅:6号窗口/骨汤麻辣烫?口味=微辣&是否放香菜=放&是否放葱=放.个性化需求是由查询字符串传递的。
  • 片段标识符:用来区分一个网页中哪个部分,常见于小说网站或者文档网站,借助片段标识符快速跳转到网页的某个部分。

URL的encode/decode

url中可能包含一些特殊含义的符号,如/ ? @等,万一query string的value中,也包含这些特殊字符,可能导致浏览器错误识别url,服务器也可能错误的解析url.(类似于变量名不能是关键字)。因此需要对特殊字符进行转义,还包括汉字。

转义规则:把待转义的字符串的每个字符按照16进制表示,每个字节前面加上%

具体可以查看这个网站:encode网站

认识方法

简单来说可以把方法理解成你这个请求想做什么

在咱们开发中,主要使用get和post方法,因此这里只介绍这两个

get方法

常用get请求的场景
  1. 浏览器地址栏中直接输入url,会触发get请求
  2. html中的link,a,img,script会触发get请求
  3. form表单
  4. ajax
如何传递信息

如果需要给服务器传递一些信息,在get请求中,通常通过querystring来传递。

post请求

常用post请求的场景
  1. form表单
  2. ajax
如何传递信息

在post请求中url通常是没有query string的,在传递信息给服务器,通常把消息放到body中

get和post的区别

  1. get和post没有本质区别,使用get实现的场景,基本可以使用post代替;使用post实现的场景,也可以使用get代替
  2. get的语义,是"从服务器获取数据",而post的语义,是"往服务器上提交数据"
  3. 从使用习惯上,给服务器传递的数据,get通常放在url的query string中;而post通常放到body中。(get请求可以把数据放到body中,post请求也可以把数据放到query string中,只是少见)
  4. get请求建议实现成"幂等",而post一般不要求实现成"幂等"。设计服务器的时候,需要提供一些"接口/api",api传入的参数,就是输入;api返回的结果,就是输出。基于get的api一般建议设计成幂等的,基于post的api则无要求。

幂等:输入是确定的,输出结果也是确定的。

  1. 在幂等基础上,get的请求结果可以被缓存(幂等的结果是确定的),而post则一般不会被缓存。

当然有的get请求不是幂等,因此要通过特殊的技巧不让浏览器产生缓存,典型做法就是让每次get请求的url都不相同,可以通过quert string来保证url不同

认识请求报头"header"

请求头中的键值对,都是标准规定的,有特定含义。

这里以访问百度网站为例www.baidu.com,进行抓包

host

表示服务器主机的地址和端口,确定是互联网上哪个主机上的哪个进程。

这里是域名,域名经过dns解析后就是ip。此处没有显示port,表示默认。http的默认端口是80,https的默认端口是443.

问url中也有这个ip+port,为什么还要有Host?

url中的Ip和端口,和host里的ip和端口,不一定完全相同。当请求是经过代理来访问的时候,有可能不一样。

content-length和content-type

  1. content-length:表示body中的数据长度
  2. contetn-type:表示body中的数据格式

如果是get请求,没有body,就没有这两个字段。如果是post请求,有body一定有这两个字段。

为什么需要content-type?

body中的数据类型有很多种格式,对于接收方来说,采取的解析方式是不同的。

为什么需要content-length?

http是基于tcp的,而tcp是面向字节流,存在粘包问题。解决方法有两种1. 约定一个分割符,也就是header和body之间的空行;2. 约定报文长度

有哪些格式?

  1. application/x-www-form-urlencoded,像html的form表单构造的请求,使用的就是这个格式。

格式和query string一样,可以放很多键值对,键值对之间用&分割,键和值之间用=分割。例如title=test&content=hello,并且这里也需要urlencode。

  1. multipart/form-data 该格式主要用于上传文件
  1. application/json数据为json格式,body格式如下

User-Agent(UA)

UA主要是浏览器信息和操作系统信息,描述了用户用什么设备上网

早期的浏览器,只支持文字,后来开始支持图片,再后来支持js,后面支持音频。在同一时间段内,用户使用多种浏览器。因此开发者就利用收集到的浏览器/操作系统信息,个性化的返回不同的页面。UA的作用大大降低

随着时间推移,浏览器都趋于一致,开发者不再需要纠结浏览器兼容问题。而现在设备主要有PC,平板,手机需要开发出不同版本的页面,后面又推出"响应式页面"能感知浏览器窗口大小,根据不同尺寸,重新排列布局。UA的作用又被削弱了

而现在UA主要用来在服务器端统计用户的设备情况

Referer

Referer指的是当前页面,是从哪个页面跳转过来的。所以直接在浏览器地址输入地址,没有referer;点收藏夹,也没有referer。

例如在百度上投放广告,采用点击计费(CPC广告)和广告主结算广告费。统计点击次数时,百度自己会统计,广告主也会统计服务器中收到的请求,有多少referer来自百度的。

cookie也是请求头的一个重要字段,是浏览器在本地存储数据的一种机制,但是只能存一些简单的键值对信息,比如存上次访问页面的时候,当前页面的访问次数,当前访问页面的身份信息。

浏览器为了安全,禁止网页js访问电脑的硬盘,浏览器专门提供了特殊的api给网页使用,可以让网页存储一些简单的数据。浏览器提供持久化存储的方案,有好几种,例如:cookie最经典的一种方案,LocalStorage和indexDB是比较新的方案。

cookie从哪来

cookie存在于浏览器,来源于服务器。

像上图,cookie是咱们浏览器访问了bing服务器之后,服务器返回的响应报文中,在响应header中包含一个或多个set-cookie这样的资源。浏览器看到set-cookie就会把这样的数据保存到浏览器本地。

cookie到哪去

cookie来自于服务器,存储于浏览器,还要再回到服务器。当浏览器保存了cookie之后,下次浏览器访问同一个网站,就会把之前本地存储的cookie,通过http请求的header的cookie带过去。

cookie的典型应用场景

cookie最常用的场景就是客服端维持登陆状态。

在某个网站上登陆成功后,浏览器就会记住当前登入用户的身份信息。然后接下来访问网站的其他页面时,服务器也能知道是谁在登入。

HTTP响应

状态码

介绍几个常见的状态码

  • 200:表示访问成功
  • 404:not found,说明请求路径写错了,请求是根据url的路径去访问服务器上的资源,如果想访问的资源,服务器没有,就会返回404
  • 403:forbidden,访问被拒绝(没有权限)
  • 500:Internal Server Error,服务器内部错误,服务器代码执行过程中,出现异常。
  • 504:Gateway Timeout,访问超时,一般是服务器请求量很大,对于服务器的负荷比较重
  • 302:重定向,访问一个旧的url自动转移到新的url上。例如服务器的地址迁移,在访问老网站时会自动帮你跳转到新网站。

1开头的表示等等

2开头的表示正常访问

3开头的表示重定向

4开头的表示客服端出现问题

5开头的表示服务端出现问题

Content-type

响应中常见的content-type

  • text/html:body的格式是html
  • text/css:body的格式是css
  • application/javascrtpt:body的格式是js
  • application/json:body的格式是json

构造HTTP请求

  1. 浏览器地址栏中输入url,构造get请求;点击a标签,构造get请求;img,link,script也会构造get请求
  2. form表单构造get/post请求,此时的content-type是x-www-form-urlencoded
html 复制代码
<form action="https://www.baidu.com" method="get">
<!--   借助下面的标签给请求构造数据,每个input对应一个键值对,
  name属性为key,input中用户输入的内容就是值
  如果是get方法,上述键值对就会出现url的query string中
  如果方法是post,上述键值对就会放到body中(格式和query string相同)-->
    <input type="text" name="username"> 
    <input type="password" name="password"> 
    <input type="submit" value="提交">
</form>
html 复制代码
<form action="https://www.baidu.com" method="post">
    <input type="text" name="username"> <br>
    <input type="password" name="password"> <br>
    <input type="submit" value="提交">
</form>
  1. ajax 各种http方法都能构造

form构造的http请求一定会触发页面跳转,而ajax默认发起的请求不会引起跳转,可以达到"局部刷新"的效果

ajax的全称是Asynchronous JavaScript And Xml

  • Asynchronous表示异步,在网络通信/IO操作中的异步表示:谁发起的请求,谁负责接收是同步,异步和同步相对,表示发起请求的主体,不负责接收结果,而是别人主动推送过来。

类似于餐馆吃饭,点完单以后,如果煮好了,自己去端是同步,等服务员帮你端过来是异步

html 复制代码
<!-- 引入第三方库,jquery -->
<script src="../jquery-1.12.4.js"></script>
<script>
    //$是jquery的全局变量,通过这个对象,可以调用里面的一些方法
    $.ajax({
        // 访问地址
        url: "https://www.baidu.com",
        type: "post", //访问方法
        data: "http请求的body", // 传给后端的数据
        contentType: 'x-www-form-urlencoded', // 构造http请求的方式
        // 后端给前端推送的结果,异步的表现
        // 使用回调函数,根据返回结果的不同执行不同的方案
        success:function(body) {
            console.log("成功")
        },
        error:function(body) {
            console.log("失败")
        }
    })
</script>
相关推荐
小堃学编程5 小时前
计算机网络(十) —— IP协议详解,理解运营商和全球网络
网络·tcp/ip·计算机网络
IPFoxy6667 小时前
探索路由器静态IP的获取方式
网络·智能路由器
menge23337 小时前
VLAN:虚拟局域网
网络·智能路由器
GZ_TOGOGO8 小时前
【2024最新】华为HCIE认证考试流程
大数据·人工智能·网络协议·网络安全·华为
ZachOn1y8 小时前
计算机网络:计算机网络概述 —— 初识计算机网络
网络·计算机网络·知识点汇总·考研必备
三金121388 小时前
SpringIoC容器的初识
网络·网络协议·rpc
狼头长啸李树身9 小时前
眼儿媚·秋雨绵绵窗暗暗
大数据·网络·服务发现·媒体
SizeTheMoment10 小时前
初识HTTP协议
网络·网络协议·http
哲伦贼稳妥11 小时前
一天认识一个硬件之机房地板
运维·网络·经验分享·其他
hgdlip12 小时前
如何快速切换电脑的ip地址
网络·tcp/ip·电脑