对于前端而言,网络部分代码不多,以概念为主。
对概念的理解程度,决定了是否能够看懂接口文档,同时也决定了是否能更好的掌控网络相关代码。
网络基本概念
客户端和服务器
在网络的世界里,两个应用程序之间会经常发生通信。
在大部分情况下,通信总是由一方发出一个消息开始,而另一方回复一个消息结束。
发出消息的一方称之为客户端 Client,发出消息的过程称之为请求 Request。
回复消息的一方称之为服务器 Server,回复消息的过程称之为响应 Response

这个过程中,有几个点需要特别注意:
不管是客户端,还是服务器,它们都是一个应用程序,而不是一台计算机。客户端和服务器可以分布在不同的计算机上,也可以在同一台计算机上,并不需要特殊看待。
比如我们之前接触的 live server 插件,就是一个服务器,它运行在本地的计算机上。
大部分后端开发的就是服务器程序,前端的 Node 技术也能开发服务器程序。
客户端和服务器的这种交互模式称之为「经典 C/S 结构」。在这种结构中,如果客户端是浏览器,则我们称之为 B/S 结构。
服务器程序往往是为互联网产品提供服务,因此又称之为 web 服务器。
一次完整的交互,总是从请求开始,响应结束。
作业
请描述什么叫做服务器、客户端、请求、响应、C/S、B/S
url
要完成一次请求和响应,首先需要让客户端找到服务器,不仅如此,还要找到服务器上我们想要的资源。
在现实生活中,如果我们要找一个人,我们可以通过一个地址来找到他。
和现实生活类似,在互联网中,我们可以通过一个叫 url 地址 的东西找到我们想要的资源。
url 全称 uniform resource locator,统一资源定位符。它是一个字符串,用于表达互联网中某个资源的位置。
url 地址示例:
- 百度首页的 url 地址:https://www.baidu.com/
- 某篇新闻页面的 url 地址:https://mbd.baidu.com/newspage/data/landingsuper?context={"nid"%3A"news_9610068257663826418"}&n_type=-1&p_from=-1
- 某知名 css 的 url 地址:https://meyerweb.com/eric/tools/css/reset/reset.css
- 某知名 js 的 url 地址:https://cdn.bootcdn.net/ajax/libs/jquery/3.6.0/jquery.min.js
- 某张图片的 url 地址:https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fup.enterdesk.com%2Fedpic_source%2F84%2F87%2F80%2F848780a296b66b382018fa7f675ecd06.jpg&refer=http%3A%2F%2Fup.enterdesk.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=auto?sec=1652600873&t=803c81d81387ec5f9fd1d92ba9d7665a
url 地址可以很长,也可以很短。
通过 url 地址可以找到互联网上的资源,它可以是页面、图片、视频、音频、css 代码、js 代码、可供下载的文件、或者其他任何东西。
一个完整的 url 地址由多个部分组成
完整的url地址
协议 + 主机 + 端口 + 路径 + 参数 + hash示例:

协议 Protocal / Schema
它表示客户端希望用什么方式和服务器沟通,现在只需要知道这里固定写 http 或 https 即可
小知识:
- 如果在浏览器的地址栏省略了协议,浏览器会自动为你补全
- 可以在 Chrome 浏览器的地址栏点击右键,显示完整的地址
- https 协议比 http 协议更安全,但往往出现在线上,本地的服务器通常不会是 https
主机 Host
它表示客户端希望在哪台计算机上寻找资源
这里有两种写法:IP 地址和域名
IP 地址。IP 地址是一个网络中计算机的唯一编号,通常,一个 IP 对应一台计算机。
记住特殊 IP 地址: 127.0.0.1,它表示本机 IP
域名。域名类似 IP 地址的别名,把不容易记忆的数字变为容易记忆的单词。当使用域名访问时,会自动转换为 IP 地址。
记住特殊域名:localhost,它表示的 IP 地址是 127.0.0.1
端口 Port
它表示客户端希望在哪个应用程序中寻找资源
每个服务器程序,都会监听一个或多个端口,只有找到对应的端口,才能找到这个服务器程序。
端口号是可选的,若不填写,则:
- 如果使用的是 http 协议,默认端口号为 80
- 如果使用的是 https 协议,默认端口号为 443
路径 Path
服务器上往往有许许多多的资源,每个资源都有自己的访问路径
路径是可选的,若不填写,则路径为 /
参数 Query / Param
某些资源可以根据需要呈现不同的内容,比如一篇新闻列表的页面,可以指定它呈现第几页的新闻,而「第几页」就属于一些额外信息,这些额外信息可以通过参数传递
比如,我们访问一个新闻列表的页面,同时希望它展示第 5 页,每页展示 10 条新闻,我们可能得到下面的 url 地址:
http://duyiedu.com/news?page=1&limit=10上面这个 url 地址中,page=1&limit=10就是参数部分,这部分可以包含多个参数,不同的参数之间使用&符号分割
参数是可选的
hash
在网络通信中,hash 没有什么用,它往往作为浏览器的锚链接出现。
作业
写出下面 url 地址中每部分的值
根据下面的需求,写出 url 地址
本地有一个服务器应用正在运行,它监听了 5500 端口,在根路径下访问 index.html 可以得到首页的内容。
请写出首页完整的 url 地址
shhttp://127.0.0.1:5500/index.html阅读下面接口文档地址的内容,写出对应的 url 地址
http
通过 url 地址,能够在茫茫互联网中准确的找到自己想要的服务。
但光找到服务还是不够,双方需要「用同一种语言」来对话,否则都听不懂对方在说什么。
这个「语言」就是协议,而互联网中最常见的协议就是 http 协议
https 是在 http 协议基础上发展起来的,它增加了安全性,其他和 http 协议完全一致
http 是基于 请求-响应 的方式完成通信的,每一次通信都是由客户端向服务器发出请求,传递一些消息过去,然后经过服务器程序处理后,响应给客户端一些消息。
http 协议规定:
每次 请求-响应 都是独立的,相互之间互不干扰。这种模式的协议我们称之为无状态协议
http 的无状态会带来一些问题,这些问题我们会在后续的课程中讨论
每次 请求-响应 传递的消息都是纯文本(字符串),而且文本格式必须按照 http 协议规定的格式书写。

请求的消息格式
请求消息格式有三部分组成

- 请求行:高度概括了客户端想要干什么
- 请求头:描述了请求的一些额外信息
- 请求体:包含了要给服务器传递的正文数据。请求体是可以省略的
请求行
请求行是整个 http 报文的第一行字符串,它包含三个部分:请求方法 路径+参数+hash 协议和版本
重点关注请求方法
请求方法是一个单词,它表达了客户端的「动作」,比如:
- GET:获取
- POST:提交
在 http 协议中,并没有规定只能使用上面两种动作,甚至没有规定每种动作会带来怎样的变化
而在实际的应用中,我们逐渐有了一些约定俗成的规范:
- 动作通常有:GET(获取资源)、POST(提交消息)、PUT(修改数据)、DELETE(删除数据)。其中,GET 和 POST 最为常见。
- GET 和 DELETE 请求不能有请求体,而 POST 和 PUT 请求可以有请求体
**浏览器遵循了上面的规范,这带来了 GET 和 POST 的诸多区别。**比如,由于 GET 请求没有请求体,所以要传递数据只能把数据放到 url 的参数中
在浏览器中,获取数据一般使用的都是 GET 请求,比如:
- 在地址栏输入地址并按下回车
- 点击了某个 a 元素
- 获取图片、音频、视频
- 获取 css、js、字体等文件
事实上,浏览器自动发出的请求基本都是 GET 请求,而 POST 请求需要开发者手动处理,比如在 form 表单中设置 method 为 POST
请求头 header
请求头是一系列的键值对,里面包含了诸多和业务无关的信息
浏览器每次请求服务器都会自动附带很多的请求头,其实这些请求头大部分服务器是不需要的
你可以说不要,但不能说我没给
我们只需关注下面几个请求头即可:
Host:url 地址中的主机
User-Agent:客户端的信息描述
Content-Type: 请求体的消息是什么格式,如果没有请求体,这个字段无意义
该字段的常见取值为:
application/x-www-form-urlencoded
表示请求体的数据格式和 url 地址中参数的格式一样,比如
loginId=admin&loginPwd=123123application/json
表示请求体的数据是 json 格式,比如
json{ "loginId": "admin", "loginPwd": "123123" }multipart/form-data
一种特殊的请求体格式,上传文件一般选择该格式
请求体 body
包含业务数据的字符串
理论上,请求体可以是任意格式的字符串,但习惯上,服务器普遍能识别以下格式:
- application/x-www-form-urlencoded:
属性名=属性值&属性名=属性值... - application/json:
{"属性名":"属性值", "属性名":"属性值"} - multipart/form-data:使用某个随机字符串作为属性之间的分隔符,通常用于文件上传
由于请求体格式的多样性,服务器在分析请求体时可能无法知晓具体的格式,从而不知道如何解析请求体,因此,服务器往往要求在请求头中附带一个属性Content-Type来描述请求体使用的格式
例如
Content-Type: application/x-www-form-urlencoded
Content-Type: application/json
Content-Type: multipart/form-data响应的消息格式
服务器(通常由后端开发)收到请求的消息后,会运行后端代码对请求进行处理,处理完成后,会给予响应。
服务器的响应格式包含三个部分

响应行
响应行是整个响应字符串的第一行。
响应行包含两个部分:
- 协议版本:表示服务器打算和客户端用什么协议通信
- 状态码、状态消息:表示服务器对当前请求的表态
通常,状态码和状态消息是一一对应的,比如状态码 200 的消息就是 OK
不同的请求可能会得到不同的状态码,至于到底会得到哪个状态码,由后端程序决定。
状态码分为五类:
| 分类 | 分类描述 |
|---|---|
| 1** | 信息,服务器收到请求,需要请求者继续执行操作 |
| 2** | 成功,操作被成功接收并处理 |
| 3** | 重定向,需要进一步的操作以完成请求 |
| 4** | 客户端错误,请求包含语法错误或无法完成请求 |
| 5** | 服务器错误,服务器在处理请求的过程中发生了错误 |
通常认为,0~399 之间的状态码都是正常的,其他是不正常的
常见的状态码有:
200 OK:一切正常。
301 Moved Permanently:资源已被永久重定向。
你的请求我收到了,但是呢,你要的东西不在这个地址了,我已经永远的把它移动到了一个新的地址,麻烦你取请求新的地址,地址我放到了响应头的Location中了302 Found:资源已被临时重定向。(浏览器会自动跳转到新地址)
你的请求我收到了,但是呢,你要的东西不在这个地址了,我临时的把它移动到了一个新的地址,麻烦你取请求新的地址,地址我放到了请求头的Location中了304 Not Modified:文档内容未被修改。(浏览器会自动跳转到新地址)
你的请求我收到了,你要的东西跟之前是一样的,没有任何的变化,所以我就不给你结果了,你自己就用以前的吧。啥?你没有缓存以前的内容,关我啥事400 Bad Request:语义有误,当前请求无法被服务器理解。
你给我发的是个啥啊,我听都听不懂403 Forbidden:服务器拒绝执行。
你的请求我已收到,但是我就是不给你东西404 Not Found:资源不存在。
你的请求我收到了,但我没有你要的东西500 Internal Server Error:服务器内部错误。
你的请求我已收到,但这道题我不会,解不出来,先睡了
响应头 header
和请求头一样,响应头也是由很多个键值对组成的,具体有哪些键值对,完全取决于服务器程序
目前,对我们最重要的键值对是Content-Type,它有多种取值,表示响应体的数据类型。
** 在 B/S 模式中,浏览器会自动根据响应头中Content-Type的取值,决定如何处理响应体。 **
text/plain: 普通的纯文本,浏览器通常会将响应体原封不动的显示到页面上text/html:html 文档,浏览器通常会将响应体作为页面进行渲染text/javascript或application/javascript:js 代码,浏览器通常会使用 JS 执行引擎将它解析执行text/css:css 代码,浏览器会将它视为样式image/jpeg:浏览器会将它视为 jpg 图片attachment:附件,浏览器看到这个类型,通常会触发下载功能- 其他
MIME类型
MIMIE 相当于给数据贴上一个标签,表明这组数据是什么类型的
响应体 body
响应的主体内容
{
"code": 200,
"msg": "success",
"data": { "name": "张三", "age": 18 }
}作业
- 使用 postman 向
http://www.douyutv.com发送 GET 请求,回答下面的问题:- 状态码是什么?表达了什么含义?
- 响应头中的 Location 的值是什么?表达了什么含义?
- 使用 postman 向
https://www.taobao.com发送 GET 请求,回答下面的问题:- 响应头中的
Content-Type的值是什么?表达了什么含义?
- 响应头中的
- 使用 postman 完成下面的作业:
- 随意使用错误的消息内容请求注册接口,观察请求头中的 Content-Type、请求体、响应的状态码、响应体、响应头中的 Content-Type
- 使用正确的消息内容请求注册接口,观察请求头中的 Content-Type、请求体、响应的状态码、响应体、响应头中的 Content-Type
浏览器页面处理流程
当在浏览器地址栏中输入一个 url 地址,并按下回车后,会发生什么?
试试这个地址:oss.duyiedu.com/test/index.html

AJAX
AJAX 就是浏览器赋予 JS 的一套 API,通过这套 API 能够使 JS 具备网络通信的能力
历史
浏览器本身就具备网络通信的能力,但在早期,浏览器并没有把这个能力开放给 JS。
最早是微软在 IE 浏览器中把这一能力向 JS 开放,让 JS 可以在代码中实现发送请求,这项技术在 2005 年被正式命名为 AJAX(Asynchronous Javascript And XML)
IE 使用了一套 API 来完成请求的发送,这套 API 主要依靠一个构造函数完成。该构造函数的名称为XMLHttpRequest,简称为XHR,所以这套 API 又称之为XHR API
由于XHR API有着诸多缺陷,在 HTML5 和 ES6 发布之后,产生了一套更完善的 API 来发送请求。这套 API 主要使用的是一个叫做fetch的函数,因此这套 API 又称之为Fetch API
无论是XHR还是Fetch,它们都是实现 ajax 的技术手段,只是 API 不同。
XHR API
var xhr = new XMLHttpRequest(); //创建发送请求的对象
xhr.onreadystatechange = function () {
//当请求状态发生改变时运行的函数
// xhr.readyState: 一个数字,用于判断请求到了哪个阶段
// 0: 刚刚创建好了请求对象,但还未配置请求(未调用open方法)
// 1: open方法已被调用
// 2: send方法已被调用
// 3: 正在接收服务器的响应消息体
// 4: 服务器响应的所有内容均已接收完毕
// xhr.responseText: 获取服务器响应的消息体文本
// xhr.getResponseHeader("Content-Type") 获取响应头Content-Type
};
xhr.open("请求方法", "url地址"); //配置请求
xhr.setRequestHeader("Content-Type", "application/json"); //设置请求头
xhr.send("请求体内容"); //构建请求体,发送到服务器,如果没有请求体,传递nullFetch API
const resp = await fetch("url地址", {
// 请求配置对象,可省略,省略则所有配置为默认值
method: "请求方法", // 默认为GET
headers: {
// 请求头配置
"Content-Type": "application/json",
a: "abc",
},
body: "请求体内容", // 请求体
}); // fetch会返回一个Promise,该Promise会在接收完响应头后变为fulfilled
resp.headers; // 获取响应头对象
resp.status; // 获取响应状态码,例如200
resp.statusText; // 获取响应状态码文本,例如OK
resp.json(); // 用json的格式解析即将到来的响应体,返回Promise,解析完成后得到一个对象
resp.text(); // 用纯文本的格式解析即将到来的响应体,返回Promise,解析完成后得到一个字符串特别注意
无论使用哪一种 API,AJAX 始终都是异步的
在初学的时候,可以把网络传输的时间想象的夸张一点,比如每一次请求和响应都要经过一年才能完成。这样有助于理解网络是异步这一点
附录
PostMan
下载地址:https://www.postman.com/downloads/
安装后需要跟随课程做一些配置以便更好的学习老师的课程
常见问题
跨域错误

这个错误通常发生在 AJAX 请求的时候,是一个跨域错误,这里需要了解什么叫跨域。
浏览器为了安全,制定了一个规则,即页面的源和请求目标的源应该保持一致,如果不一致,就产生了跨源或者叫跨域。
源 = 协议 + 主机 + 端口
比如:
| 页面源 | 目标源 | 是否跨域 |
|---|---|---|
| https://baidu.com/news.html | http://103.231.13.42/1.jpg | 是 |
| https://www.baidu.com/news.html | http://baidu.com:8080/1.jpg | 是 |
| https://baidu.com/news.html | https://baidu.com/1.jpg | 否 |
- 浏览器对 img、link、script 的限制比较宽松,一般允许跨域
- 浏览器对 AJAX 比较严格,一般不允许跨域
浏览器对跨域行为作出的不同限制,统称为同源策略
如果在 AJAX 中出现跨域请求,就会报出以上错误。
但如果服务器明确告知浏览器允许跨域,则浏览器会允许 AJAX 跨域请求。
404 错误

浏览器请求某个资源,但服务器响应了一个 404 状态码,就会在控制台中报出这个错误。与此同时,你可以在浏览器的网络调试中进一步观察到这个错误。
404 错误是一种非常常见的错误,它表示服务器告诉客户端:你要的资源并不存在
要解决这个错误,首先要检查请求的 url 地址是否正确。如果 url 地址正确,则可能是服务器的问题,需要联系后端开发人员或者将问题上报
favicon

报错内容:加载资源失败:服务器响应了 404 状态码
请求地址::5500/favicon.ico
原因:
很多浏览器在解析页面后,如果发现页面中并没有使用link元素加载站点图标,会尝试请求以下地址来获取图标:
站点协议://站点主机:站点端口/favicon.ico
如果这个地址无法获得图标,就会报出相应错误
该错误会在下一次刷新后消失,是因为再次刷新后,浏览器记忆了之前无法获取图标的情况,就不再发出请求了。
其他问题
网络断开,检查你的网络连接,或者检查你是否在调试工具中进行了网络断开调试
访问的域名不存在,无法连接到服务器

