Node.js理论-Web的基本运作原理
一、前言
在学习node.js的过程中,Web的基本运作原理非常重要,因为node.js的本质就是在服务器运行一个JavaScript环境,它的核心任务之一就是来处理Web请求。所以,你必须知道这背后发生了什么
二、Web基础-客户端与服务端
整个Web世界都是建立在客户端和服务段的结构之上;
客户端:通常指的是你的浏览器,也可以是APP、命令行工具等等的一切。它负责发起请求,等到收到数据之后,将你收到的数据渲染成你看懂的页面;
服务器:它本质就是一台计算器,上面运行着Web的服务器程序,比如你写的Node.js的程序,它主要负责监听请求、处理逻辑,并且返回响应;
三、当我们打开一个WEB界面发生了什么?
最基础就是请求和响应,客户端请求,服务器端响应;这通常被我们成为请求-响应模型或者客户端-服务器架构

3.1从URL到页面显示
当我们打开浏览器,输入https://nodejs.org/docs/并按下回车,到底发生了什么呢
3.1.1 解析URL
浏览器首先会分析一下这个URL,这个URL是什么组成的呢?
- https: 协议,告诉浏览器我们是用什么方式来进行通信的;
- nodejs.org: 域名,这个代表我们要找哪一台服务器;
- docs:资源,这个表示我们想要服务器去访问哪个资源;

3.3.2 域名并不是真正的服务器地址
网络中计算器只能通过一个IP地址来访问,但是IP对于人类来说并不易记,于是会有一个DNS服务器来告诉你nodejs.org的真实IP地址是多少。这个DNS服务器像是之前农村的固话电话本,里面记录着这个IP我们怎么去获取它;

3.3.3 通过TCP/IP socket connection建立连接
在建立联系之前,要先建立可靠的连接,TCP是可靠的传输控制协议,一般情况下,我们只需要知道这些就可以了;但是这里简单的说一下是如何进行建立的,这种可靠的连接是通过TCP/IP的三次握手来进行建立的,可以简单理解为:
- 客户端:发送SYN,请求连接("我可以连接你吗?")
- 服务端:回复SYN-ACK,确认信息("可以的,你能听见我讲话吗?")
- 客户端:发送ACK,确认信息("可以听到了,我们来建立简介吧")
上面就是一个简单的HTTP建立连接的过程,如果是HTTPS连接,建立连接之后还会进行TLS握手,交换证书、协商密钥,确保后续的通信都是加密的;

3.3.4 发送HTTP请求
建立连接之后,浏览器会拼装一条HTTP请求报文,发送给服务器,下面是一个HTTP请求示例
http
GET /chat?session=agent%3Amain%3Amain HTTP/1.1
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9,en;q=0.8
Cache-Control: no-cache
Connection: keep-alive
Host: www.example.com
Pragma: no-cache
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/147.0.0.0 Safari/537.36 Edg/147.0.0.0
一般情况下一个HTTP请求由三部分组成
- 请求行:例如方法(GET)、路径、HTTP版本;
- 请求头:关于浏览器、期望的格式、Cookie信息等等;
- 请求体:GET请求通常是没有Body,如果post请求,Body里面会包含一些提交的数据,例如表单字段或者JSON
3.3.5 服务器处理----Node.js登场
请求是通过服务器的某个端口,默认情况下HTTP的端口是80,HTTPS的端口是443,你的node.js程序就在这个端口监听的,这个代码我们之前已经写过了,例如
js
const server = http.createServer((request, response) => {
// console.log(request.url)
// console.log(url.parse(request.url,true));
const { query, pathname } = url.parse(request.url, true);
//主页
if (pathname === '/' || pathname === '/overview') {
response.writeHead(200, { 'content-type': 'text/html' });
const cardsHtml = dataObj
.map((el) => replaceTemplate(tempCard, el))
.join('');
const outTemp = tempOverview.replace('{%PRODUCT_CARDS%}', cardsHtml);
response.end(outTemp);
//产品页
} else if (pathname === '/product') {
response.writeHead(200, { 'content-type': 'text/html' });
const product = dataObj[query.id];
const output = replaceTemplate(tempProduct, product);
response.end(output);
} else if (pathname === '/api') {
response.writeHead(200, { 'content-type': 'application/json' });
response.end(data);
} else {
response.writeHead(200, { 'content-type': 'text/html' });
response.end('页面不存在!');
}
});
server.listen(8000, '127.0.0.1', () => {
console.log('服务器正在运行,访问地址:http://127.0.0.1:8000');
});
3.3.6 返回HTTP响应
服务区处理完成之后就会构造一个HTTP响应报文,一般情况下响应报文是这样的
js
HTTP/1.1 200 OK
X-Content-Type-Options: nosniff
Referrer-Policy: no-referrer
Permissions-Policy: camera=(), microphone=(), geolocation=()
X-Frame-Options: DENY
Content-Security-Policy: default-src 'self'; base-uri 'none'; object-src 'none'; frame-ancestors 'none'; script-src 'self' 'sha256-RxCZFmTWY/yQmhYxMDn+blaCuwLzOsV/XsVb0n5EkRU='; style-src 'self' 'unsafe-inline' https://fonts.googleapis.com; img-src 'self' data: https:; font-src 'self' https://fonts.gstatic.com; connect-src 'self' ws: wss:
Content-Type: text/html; charset=utf-8
Cache-Control: no-cache
Date: Tue, 28 Apr 2026 04:02:51 GMT
Connection: keep-alive
Keep-Alive: timeout=5
Content-Length: 3395
一般情况下,也是由三部分组成
- 状态行:这里包含了一些HTTP版本,状态码,状态消息(常见200成功、3xx重定向、404未找到页面、500服务器错误等等);
- 响应头:返回内容的类型、长度、服务器信息、要设置的Cookie等等;
- 响应体:这个是实际的数据,可能是HTML页面、JSON文本、图片、CSS文件等等;
3.3.7 浏览器收到之后开始解析
一般情况下,index.html是第一个被加载的文件,收到之后,会构建DOM树,扫描js、css、图片等资源,当然每个文件都会重复这个动作;最后合成渲染树并绘制出来,这样一个完整的页面就被你看到了
四、HTTP的几个补充关键点
- 为什么我们需要Cookie、Session、Token这些东西?
这些东西是来维持登录状态的,浏览器的所有请求都是无状态的,服务器并不知道你之前请求过什么,后面我们会学习怎么去处理这些状态;
- 请求-响应模型默认情况下不存在服务器主动推送任何数据,除非你是用了一些WebSocket的一些东西,Node.js也是严格遵循这个原则
五、学习Node.js为什么我们需要了解这些东西呢?
之前我们使用node.js创建服务器,你真的知道req这个对象来自于哪里吗?这个里面有什么东西吗?res对象要发到哪里去呢?我们怎么设置状态码和头部呢?为什么路由要和URL路径匹配?以后学习HTTP模块、EXPRESS、Koa框架有非常大的作用!