HTTP 全解

166 阅读10分钟

博客内容来自饥人谷、b站up主技术蛋老师,峰华前端工程师,感谢精彩分享

上网流程

上网流程内容
浏览器地址栏输入 网页的URLbaidu.com
DNS解析域名与IP对应起来的库
浏览器向电信或联通提供的 DNS服务器询问 域名对应的 IP
发送 HTTP 请求浏览器会向对应 IP的 443 端口发送请求
请求内容是查看baidu.com的首页
服务器响应浏览器渲染网页

万维网三大标准

标准内容备注
统一资源标识符 URL表示各种资源的互联网地址URL 也叫网址,由以下几部分组成:
协议 + 域名(主机) + 路径 + 查询参数 + 锚点
超文本传输协议 HTTP负责规定客户端和服务器怎样互相交流
超文本标记语言 HTML定义超文本文档的结构和格式
URL相关概念内容备注
协议协议就是浏览器请求服务器资源的方法
邮件地址协议mailto:
HTTP协议 http://
HTTPS协议 https://
上网就是客户端发送请求报文,服务端收到请求以后就回送响应报文,这两个报文的格式由HTTP规定。
域名
(IP 的别称)
资源所在的网站名或服务器的名,又称主机host一个域名对应不同 IP:
顶级域名.com
二级域名baidu.com
三级域名www.baidu.com
路径请求不同的页面
查询参数请求同一页面的不同内容www.baidu.com/s?wd=hello
锚点网页内部的定位点
请求同一页面、同一内容、不同位置
锚点名,在网址的最后,加载页面后自动滚动到锚点所在位置
#位置
IP和端口作用备注
IP定位一台设备
路由器(网关) :pc和手机通过此连接外网。
外网IP是你在互联网中的地址,不固定 用ip138查询
内网IP是路由器创建分配给设备 192.168.xxx.xxx
通过路由器(网关)中转实现内网设备访问外网设备
特殊的IP:127.0.0.1表示自己
port 端口用来定位一个设备的服务
同一域名下包含多个网站,通过端口区分
0 ~ 1023是给系统用的
服务器默认用 80 端口 提供 HTTP 服务
服务器默认用 443 端口 提供 HTTPS 服务

HTTP 协议

HTTP是一个客户端(用户)和服务端(网站)之间请求和应答的标准。

请求报文

请求有8种方法,常用的有GETPOST

常用的请求方法说明备注
GET获取资源从指定资源中请求数据,只用于数据的读取。
GET请求的不安全性,在地址栏和历史记录中明文显示
一般没有请求体
POST创建资源
提交数据
请求数据会被包含在请求体中。比如 表单数据提交、文件上传
POST请求永远不会被缓存,且对数据长度没有限制;我们无法从浏览器历史记录中查找到POST请求

image.png

请求报文内容
请求行
Request-Line
请求方式 路径加查询参数 协议名/版本
请求头
Request Headers
Accept
Content-Type 请求体格式
空行表示 请求头 结束
请求体
Request body
即上传的内容
在 GET 请求中为空
GET /comments?postId=1 HTTP/1.1      
Host: 域名或IP
Accept: text/html
Content-Type: text/javascript;charset=utf-8 
                            

方法就是客户端请求服务器对资源执行某些动作

响应报文

image.png

响应报文内容
状态行
Response-State
协议名/版本 状态码 状态码含义描述
响应头
Response Headers
包含额外的响应信息:告知客户端如何控制缓存和Cookie
Content-Type 响应体格式
空行表示 响应头 结束
响应体
Response body
即下载的内容,服务端返回的数据
在 GET 请求中为空
HTTP/1.1 200 OK
Content-Type:text/html;charset=utf-8

// 响应体(即下载内容)
// 状态码
1xx 消息 // 请求已被服务器接收,继续处理
2xx 成功 // 请求已被服务器接收,理解、并接受
    201 Created 已创建
    204 No Content 无内容
3xx 重定向    // 让浏览器执行某些特别的处理 ,需后续操作
    301 Move Permanently 永久移动(资源永久更新了URL302 Found 临时移动 (给你临时URL 下次还得用旧地址)
    304 Not Modified 未修改 (没过期 直接使用缓存的内容)
4xx 客户端错误 // 请求含有词法错误或者无法被执行
    400 Bad Request 语法错误
    401 Unauthorized 身份认证
    403 Forbidden 拒绝(没权限)
    404 Not Found 找不到资源或路径
    409 Conflict 冲突 (新老版本对齐)
5xx 服务器错误 // 服务器在处理某个正确请求时发生错误
    500 Internal Server Error 服务器内部错误或故障
    502 Bad Gateway 网关错误
    503 Service Unavailable 超载或维护
    

HTTP 无状态

每次客户端发出的不同请求,服务器是不知是同一来源,可以用 CookieSession 来记录状态。

image.png

Cookie

本质就是存储在浏览器的数据。

是用户浏览网站时,由服务器创建并由浏览器存放在本地或其他设备上的小文本文件。每次HTTP请求都自动带数据给服务器的技术。

浏览器发起 HTTP 请求,服务器会进行 Cookie 设置,即Set-Cookie: {Name: egg, Value: 2023},服务器将 Cookie 发给浏览器,浏览器会保存起来,浏览器以后发送的每个请求都会自动附上Cookie

Cookie 用途内容
会话管理用户登录后,服务器下发给客户端一个cookie,包含唯一会话标识符
用户登录成功时,服务器对标识符身份验证,授予用户访问其服务的权限
个性化存储用户偏好设置
后来由 LocalStorage替代
跟踪记录用户购买习惯等
Cookie 分类内容
会话 cookieSession 用户浏览网站时临时存储
持久性 cookie只在其创建者设置的特定日期后过期,期间一直有效
安全 cookie只能通过HTTPS传输

Session

JWT

web 存储

image.png

如何发请求和做响应

请求与响应内容备注
发请求(用浏览器地址栏)发请求的工具叫做用户代理Chrome就是用户代理
发请求(用 Curl 命令)Curl 就是用户代理
做响应(用 Node.js 的http模块)------
  • 响应服务器代码:
// 每次收到请求都会把代码执行一遍 用 if else 判断路径,并返回响应
// 所有路径都以 / 开头;如果是已知路径,一律返回 200 ; 未知路径返回 404
if(path === '/'){
  response.statusCode = 200
  // Content-Type 决定文件类型
  response.setHeader('Content-Type', 'text/html;charset=utf-8')
  response.write(`
    <!DOCTYPE html>
    <head>
      <link rel="stylesheet" href="/x">
    </head>
    <body>
      <h1>标题<h1>
      <script src="/y"></script>
    </body>
  `)
  // 响应可以发给用户了
  response.end()
} else if(path === '/x'){
  response.statusCode = 200
  response.setHeader('Content-Type', 'text/css;charset=utf-8')
  response.write(`body{color: red;}`)
  response.end()
} else if(path === '/y'){
  response.statusCode = 200
  response.setHeader('Content-Type', 'text/javascript;charset=utf-8')
  response.write(`console.log('这是JS内容')`)
  response.end()
} else {
  response.statusCode = 404
  response.setHeader('Content-Type', 'text/html;charset=utf-8')
  response.write(`你输入的路径不存在对应的内容`)
  response.end()
}

开启服务器:node server.js 8888

image.png

image.png

JS 发 HTTP 请求的常用方法

标题说明备注
Ajax发出异步HTTP请求的传统方式用HTTP POST方法发送数据,用HTTP GET方法接收数据。
$.ajaxjQuery Ajax 是进行HTTP调用的最简单方法之一$.ajax方法需要许多参数,其中一些是必需的,另一些是可选的。它包含两个回调选项successerror处理收到的响应。
fetch是 Web API,返回Promise
Axios返回Promise

AJAX

// 初始化一个新 XMLHttpRequest 方法
const Http = new XMLHttpRequest();
const url = 'https://jsonplaceholder.typicode.com/posts';
// 指定 URL 端点和 HTTP 方法,使用 open()方法将 HTTP方法和URL端点绑定在一起
Http.open("GET", url);
// 调用 send() 方法触发请求
Http.send();
// 监听事件触发时调用事件处理程序的属性将 HTTP 响应记录
Http.onreadystatechange = function(){
  if(this.readyState === 4 && this.status === 200){
    console.log(Http.responseText)
  }
}
// readyState 和 status允许我们可以检查请求的状态

jQuery Ajax

$(document).ready(function(){
  const Url = 'https://jsonplaceholder.typicode.com/posts';
  $('.btn').click(function(){
    const data = {name:"Said",id:23};
    $.ajax({
      url: Url,
      type: "GET", // or POST
      // data: data  (if the type is POST)
      // dataType: JSON or HTML, XML, TXT, jsonp
      success: function(reasult){
        console.log(reasult)
      },
      error:function(error){
        console.log(`Error ${error}`)
      },
    })
  })
})
// $.get 方法用于执行 GET 请求,需要两个参数:请求地址、回调函数
const Url = 'https://jsonplaceholder.typicode.com/posts';
$('.btn').click(function(){
  $.get(Url, function(data, status){
    console.log(`${data}`)
  });
}
// $.post 方法用于将数据发布到服务器的另一种方法。
// 它需要三个参数:请求的url地址、您要发送的数据、回调函数
const Url = 'https://jsonplaceholder.typicode.com/posts';
const data = {
  name:"Said",
  id:23
}
$('.btn').click(function(){
  $.post(Url, data, function(data, status){
    console.log(`${data} and status is ${status}`)
  });
}
// $.getJSON 方法检索 JSON格式的数据,需要两个参数 url、回调函数
const Url = 'https://jsonplaceholder.typicode.com/posts';
$('.btn').click(function(){
  $.getJSON(Url, function(result){
    console.log(result)
  });
}

Fetch

const Url = 'https://jsonplaceholder.typicode.com/posts';
fetch(Url)
.then(data => {return data.json()})
.then(res => {console.log(res)})
const Url = 'https://jsonplaceholder.typicode.com/posts';
const data = {
  name:"Said",
  id:23
};
const otherPram = {
  headers:{
    "content-type":"application/json; charset=UTF-8"
  },
  body: Data,
  methods: "POST"
};
fetch(Url, otherPram)
.then(data => {return data.json()})
.then(res => {console.log(res)})
.catch(error => console.log(error))

Axios

const Url = 'https://jsonplaceholder.typicode.com/posts';
const user = {
  name:"Said",
  id:21
}
axios({
  method: 'post',
  url: Url,
  data: { user }
})
.then(data => {return data.json()})
.catch(error => console.log(error))

HTTP版本

各种版本说明 (向下兼容)
HTTP/0.9只接受GET一种请求方法,已过时
HTTP/1.0第一个在通讯中指定版本号的HTTP协议版本
HTTP/1.1默认采用持续连接(Connection: keep-alive)缓存处理
HTTP/2当前版本(2015年发布)
数据通过二进制传输、多路复用、压缩头、支持 Server Push
HTTP/3最新版本(2022年标准化为RF9114)

HTTP 缓存

为了重复使用而被存储数据,减少服务器和客户端之间的通信次数,降低网络延迟,加速页面加载,提高用户体验。

HTTP协议规定缓存是如何工作,如何存储和各种类型的。即HTTP产生的缓存,Web缓存。

HTTP 缓存类型

  • 浏览器缓存:浏览器帮用户保存一些缓存内容;
  • 代理缓存:在客户端和源服务器之间,备份源服务器的资源作为缓存;
  • 数据库缓存:对数据库的重复资源操作(CRUD)。

HTTP 缓存如何工作

请求资源,先看看自己有没有缓存;若无就问服务器索要;若有,就检查缓存是否过期,若未过期,就直接用,若过期了,就和服务器进行验证,服务器告知没有过期,就继续使用缓存,若已过期,就返回新资源作为新的缓存。

HTTP 控制缓存操作的首部(Response Headers)

cache-control:no-cache // 可进行缓存,使用前要和服务器确认

cache-control:max-age=31536000 // 资源保存为缓存的最长时间 单位s 即1年

expires: Sun, 31 Jul 2022 18:19:11 GMT // 缓存的过期时间
last-modified: Wed, 28 Jul 2021 08:04:46 GMT  // 资源最后的修改时间

HTTPS 协议

基于HTTP协议中,请求和响应的报文都是明文的,网络上涉及到美金的地方,就需要考虑安全。所以HTTPS出现,原理就是在HTTP基础上用TLS/SSL进行加密,使通信不容易受到拦截和攻击。

加密方式

对称加密:发送和接收方用同样的规则(算法G)为数据加密。用同样的钥匙解密文。第三方知道加密规则就很容易破解。

非对称加密(公钥加密):用两个密钥(私钥+公钥)来进行加密和解密,私钥放在服务器里,数据经过公钥加密就只能被私钥解密,数据经过私钥加密就只能被公钥解密,

image.png

SSL证书

服务端需要申请SSL证书,来解决用户能快速找对目标服务器的问题。比如B站的域名一输错,容易给不法分子伪装让用户访问,所以B站需要申请SSL证书,来证明这个域名的合法性。

SSL证书是保存在源服务器的数据文件,要让SSL证书生效需要向CA证书授权中心申请。证书里包括了特定的公钥和私钥,服务器安装了证书,用户可通过HTTPS访问服务器。

浏览器会把HTTP的默认端口80改为HTTPS的默认端口443,

SSL 加密安全协议

SSL是TSL的前身,绝大部分浏览器不支持SSL

TLS 加密安全协议(TLS1.2)

用的是对称和非对称加密。浏览器通过HTTPS访问服务器根据不同的TLS版本会有不同的变化。