1、基本概念
URL
Uniform Resource Locator,统一资源定位符。用于表示互联网上某一个资源的位置。
端口
端口用于寻找服务器中某一个应用程序。每一个服务端应用程序都会监听一个或多个端口。
http 协议默认端口号为 80,https 协议默认端口号为 443 。
http 协议
- 每一次“请求 - 响应”都是独立、互不影响的,这种模式称为无状态协议。
- “请求 - 响应”传递的消息都是纯文本,文本格式有对应的规范。
请求消息的格式
请求消息分为三个部分:
- 请求行:概括客户端发送该请求的目的。
- 请求头:包含该请求的一些额外数据。
- 请求体:包含传递给服务器的正文数据。
请求行
请求行包含三个部分:请求方式、路径 + 参数 + 哈希值,请求的协议和版本。
关于请求方式,实际上 http 协议并没有规定每一种方式有什么不同的规范。只是在实际的应用中,为了便于理解,有了一些约定俗成的规范:
GET- 获取POST- 提交PUT- 修改DELETE- 删除
其中,GET 和 DELETE 请求没有请求体,POST 和 PUT 请求可以有请求体。
浏览器自动发出的请求基本上都是 GET 请求,例如请求 js、css 及图片等静态资源,访问、跳转页面等。
请求头
-
Host:url中的主机 + 端口号。 -
User-Agent:发送请求的客户端相关信息。 -
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 这些是文本数据,图片、文件、excel、pdf 等资源则是二进制数据。
2、浏览器请求页面的流程
- 浏览器对
url进行补全(如有需要,根据当前页面的协议对省略的协议部分进行补全;如果在空白页,则补全为file://,意为在本地文件系统); - 对
url中的非ASCII字符进行URL编码,也称为百分比编码(如中文字符); - 向服务器发送请求;
- 服务器返回
HTML文档; - 丢弃旧页面;
- 解析
HTML文档内容; - 发现
link标签,暂停解析,向服务器发送请求; - 服务器返回
CSS文件; - 解析并应用
CSS样式; - 发现
img元素,向服务器发送请求,不暂停解析; - 服务器返回图片资源;
- 将图片渲染到页面上,继续解析
HTML; - 发现
script元素,暂停解析,向服务器发送请求; - 服务器返回
JS代码; - 执行
JS代码; - 继续解析
HTML直至解析完成。
3、AJAX
浏览器将部分网络通信的能力开放给 JS,使得 JS 可以在代码中实现网络通信,这一项技术被称为 AJAX - Asynchronous Javascript And XML。
实现网络通信主要有两套 API,它们都是实现 AJAX 的技术手段:
XHR - XMLHttpRequest(旧)Fetch API(新)
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;此时请求才发送出去
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即可解决,表示允许跨域的来源。