网络小记

45 阅读6分钟

1、基本概念

URL

Uniform Resource Locator,统一资源定位符。用于表示互联网上某一个资源的位置。

端口

端口用于寻找服务器中某一个应用程序。每一个服务端应用程序都会监听一个或多个端口。

http 协议默认端口号为 80https 协议默认端口号为 443

http 协议

  • 每一次“请求 - 响应”都是独立、互不影响的,这种模式称为无状态协议
  • “请求 - 响应”传递的消息都是纯文本,文本格式有对应的规范。

请求消息的格式

请求消息分为三个部分:

  1. 请求行:概括客户端发送该请求的目的。
  2. 请求头:包含该请求的一些额外数据。
  3. 请求体:包含传递给服务器的正文数据。
请求行

请求行包含三个部分:请求方式、路径 + 参数 + 哈希值,请求的协议和版本

关于请求方式,实际上 http 协议并没有规定每一种方式有什么不同的规范。只是在实际的应用中,为了便于理解,有了一些约定俗成的规范:

  • GET - 获取
  • POST - 提交
  • PUT - 修改
  • DELETE - 删除

其中,GETDELETE 请求没有请求体,POSTPUT 请求可以有请求体。

浏览器自动发出的请求基本上都是 GET 请求,例如请求 jscss 及图片等静态资源,访问、跳转页面等。

请求头
  1. Hosturl 中的主机 + 端口号。

  2. User-Agent:发送请求的客户端相关信息。

  3. Content-Type:请求体数据的格式,用一个 MIME 类型的字符串表示。(仅当有请求体时才有意义)

常用的请求体数据格式:

  • application/x-www-form-urlencoded

表示请求体数据和 url 中参数的格式一样。例如:name=a&sex=b

  • application/json

表示请求体数据是 json 格式。例如:{ "name": "a" }

  • multipart/form-data

处理多部分数据的格式,通常用于上传文件。

请求体

服务器会根据请求头中 Content-Type 的值解析请求体数据。

响应消息的格式

响应行

响应行包含两部分:响应的协议和版本,状态码 + 状态信息

状态码分类

  • 1** 信息。表示服务器收到请求,需要请求者继续执行操作。
  • 2** 成功。表示请求成功被服务器接收并处理。
  • 3** 重定向。表示需要进一步操作以完成请求。
  • 4** 客户端错误。表示请求中包含语法错误,或无法完成请求。
  • 5** 服务器错误。表示服务器在处理请求的过程中发生了错误。

常见的状态码:

301 Moved Permanently: 资源已被永久重定向。表示请求的内容被移动到了其它位置,新的路径通过响应头中的 Location 字段返回。

浏览器收到这个状态码会自动解析 Location 中的新路径,并重新发起新请求

302 Found:资源被临时重定向。

301 一样,新的路径会通过 Location 字段返回。不同的是:浏览器会将 301 返回的新路径缓存下来,下次请求直接从缓存中请求新路径

304 Not Modified:请求的内容与上一次请求相比没有变化。浏览器会从缓存中读取上一次的内容。

400 Bad Request:语义有误,请求无法被服务器解析。

403 Forbidden:服务器收到请求,但拒绝执行。

500 Interval Server Error:服务器内部错误。表示服务器执行请求时发生了错误。

响应头

和请求头一样,响应头中也有很多键值对,例如上面介绍的 Location 字段。

响应头中的键值对都是由服务器配置添加的,我们重点关注 Content-Type 字段。这个字段表示请求体内容的格式

Content-Type 值举例:text/plain, text/html, text/javascript, text/css, image/png, attachment(附件), 其它 MIME 类型。

响应体

html, js, css 这些是文本数据,图片、文件、excelpdf 等资源则是二进制数据

2、浏览器请求页面的流程

  1. 浏览器对 url 进行补全(如有需要,根据当前页面的协议对省略的协议部分进行补全;如果在空白页,则补全为 file://,意为在本地文件系统);
  2. url 中的非 ASCII 字符进行 URL 编码,也称为百分比编码(如中文字符);
  3. 向服务器发送请求;
  4. 服务器返回 HTML 文档;
  5. 丢弃旧页面
  6. 解析 HTML 文档内容;
  7. 发现 link 标签,暂停解析,向服务器发送请求;
  8. 服务器返回 CSS 文件;
  9. 解析并应用 CSS 样式;
  10. 发现 img 元素,向服务器发送请求,不暂停解析
  11. 服务器返回图片资源;
  12. 将图片渲染到页面上,继续解析 HTML
  13. 发现 script 元素,暂停解析,向服务器发送请求;
  14. 服务器返回 JS 代码;
  15. 执行 JS 代码;
  16. 继续解析 HTML 直至解析完成。

3、AJAX

浏览器将部分网络通信的能力开放给 JS,使得 JS 可以在代码中实现网络通信,这一项技术被称为 AJAX - Asynchronous Javascript And XML

实现网络通信主要有两套 API,它们都是实现 AJAX 的技术手段

  • XHR - XMLHttpRequest (旧)
  • Fetch API (新)
  1. XHR 代码示例:
const xhr = new XMLHttpRequest();
xhr.onreadystatechange = function () {

    // xhr.readyState 表示当前请求到了哪个阶段
    // 1 - open 方法已调用
    // 2 - send 方法已调用
    // 3 - 接收到响应消息的响应头,开始接收响应体
    // 4 - 接收到响应详消息的响应体,请求完成
    
    // xhr.responseText 服务器响应的消息体文本
    
    // xhr.getResponseHeader("content-type"); 获取响应头中的信息
}
xhr.open("GET", "/xxx/xxx"); // 配置请求的方法及路径
xhr.setRequestHeader("content-type", "application/json"); // 设置请求头中的字段
xhr.send(); // 发送请求体,GET 请求传 null;此时请求才发送出去
  1. Fetch 代码示例:
fetch("/xxx/xxx", {
    method: "POST",
    headers: {
        "content-type": "application/json"
    },
    body: {
        name: "Toby"
    }
}).then(res => {
    // 此处获取到响应消息的响应头,通过 json 或 text 方法获取响应体内容
    res.json().then(res => {
        // 此处获取到响应体
    });
});

4、跨域

  • 协议 + 主机 + 端口)。
  • 当前页面的源与目标请求的源不一致,为跨源(跨域)。
  • 跨域是浏览器的安全限制,实际上请求和响应是正常进行的,只是浏览器将响应的结果封锁了
  • 浏览器对 link, image, script 标签发出的请求一般不进行跨域检查,对 AJAX 请求会做跨域检查。
  • 服务器返回响应时,在请求头中加上 Access-Control-Allow-Origin 即可解决,表示允许跨域的来源。