小满zs专栏:juejin.cn/column/7274...
http 模块
用于创建和处理 HTTP 服务器和客户端的核心模块。可创建 Web 服务器、代理服务器、文件服务器等
- demo
JavaScript
const http = require('node:http'); // 引入 http 模块
const url = require('node:url'); // 引入 url 模块
// 创建 HTTP 服务器,并传入回调函数用于处理请求和生成响应
http.createServer((req, res) => {
const { pathname, query } = url.parse(req.url, true); // 解析请求的 URL,获取路径和查询参数,传 true 是让 query 以对象格式输出
if (req.method === 'POST') { // 检查请求方法是否为 POST
if (pathname === '/post') { // 检查路径是否为 '/post'
let data = '';
req.on('data', (chunk) => {
data += chunk; // 获取 POST 请求的数据
console.log(data);
});
req.on('end', () => {
res.setHeader('Content-Type', 'application/json'); // 设置响应头的 Content-Type 为 'application/json'
res.statusCode = 200; // 设置响应状态码为 200
res.end(data); // 将获取到的数据作为响应体返回
});
} else {
res.setHeader('Content-Type', 'application/json'); // 设置响应头的 Content-Type 为 'application/json'
res.statusCode = 404; // 设置响应状态码为 404
res.end('Not Found'); // 返回 'Not Found' 作为响应体
}
} else if (req.method === 'GET') { // 检查请求方法是否为 GET
if (pathname === '/get') { // 检查路径是否为 '/get'
console.log(query.a); // 打印查询参数中的键名为 'a' 的值
res.end('get success'); // 返回 'get success' 作为响应体
}
}
}).listen(98, () => {
console.log('server is running on port 98'); // 打印服务器启动的信息
});
反向代理
充当服务器和客户端之间的中介,将客户端的请求转发到一个或多个后端服务器,并将后端服务器的响应返回给客户端
用于负载均衡、高可用性、缓存和性能优化、安全性、域名和路径重写
- demo
JavaScript
const http = require('node:http');
const fs = require('node:fs')
const url = require('node:url')
const html = fs.readFileSync('./index.html') //给html文件起个服务
const {createProxyMiddleware} = require('http-proxy-middleware')
const config = require('./xm.config.js')
const server = http.createServer((req, res) => {
const {pathname} = url.parse(req.url)
const proxyList = Object.keys(config.server.proxy) //获取代理的路径
if(proxyList.includes(pathname)){ //如果请求的路径在里面匹配到 就进行代理
const proxy = createProxyMiddleware(config.server.proxy[pathname]) //代理
proxy(req,res)
return
}
console.log(proxyList)
res.writeHead(200, {
'Content-Type': 'text/html'
})
res.end(html) //返回html
})
server.listen(80) //监听端口
- 反向代理服务器通过
http-proxy-middleware
与html文件做关联,接收html文件传来的请求,并反向代理到目标服务器 - xm.config.js 配置文件
JavaScript
module.exports = {
server:{
proxy:{
//代理的路径
'/api': {
target: 'http://localhost:3000', //转发的地址
changeOrigin: true, //是否有跨域
}
}
}
}
动静分离
将动态生成的内容(如动态网页、API请求)与静态资源(如HTML、CSS、JavaScript、图像文件)分开处理和分发,通过将动态内容和静态资源存储在不同的服务器或服务上,并使用不同的处理机制
实现动静分离的方法:
- 使用反向代理服务器(如Nginx、Apache)将静态请求和动态请求转发到不同的后端服务器或服务
- 将静态资源部署到CDN上,通过CDN分发静态资源,减轻源服务器的负载
- 使用专门的静态文件服务器(如Amazon S3、Google Cloud Storage)存储和提供静态资源,而将动态请求交给应用服务器处理
JavaScript
import http from 'node:http' // 导入http模块
const server = http.createServer((req, res) => {
const { url, method } = req
// 处理静态资源
if (method === 'GET' && url.startsWith('/static')) {
}
// 处理动态资源
if ((method === 'GET' || method === 'POST') && url.startsWith('/api')) {
}
})
server.listen(80) // 监听端口80
模拟:现有一页面上有静态资源和动态资源,用户请求该页面的域名的后续过程
-
用户首先发送请求到服务器,请求页面。
-
服务器接收到请求后,通过动静分离技术,将请求的处理分为请求静态资源和请求动态资源两部分。动态内容由应用服务器处理,而静态内容由专门的静态服务器处理。
-
对于用户请求的动态资源,如API请求,服务器直接处理并返回相应的数据。这些数据通常是根据用户的请求参数,或存储在数据库中的数据动态生成的。
-
对于用户请求的静态资源,如图片、CSS、JS文件等,服务器将请求转发到CDN(内容分发网络)。
-
CDN查看是否有缓存的静态资源,如果有就直接返回给用户,如果没有则向源服务器请求该静态资源。
-
原服务器把静态资源提供给CDN,CDN将资源保存在缓存中,并同时将资源返回给用户。
-
用户的浏览器接收到返回的动态和静态资源,进行页面的渲染。
第一步中的服务器通常为应用服务器,用户请求首先会被发送到应用服务器,对于静态资源的请求,应用服务器通常会将请求重定向到CDN或静态资源服务器
应用程序框架 express
基于Node.js的HTTP模块而创建的,简化了处理HTTP请求、响应和中间件的过程
路由模块化、中间件生态系统、视图引擎支持
- demo
JavaScript
import express from 'express';
import User from './src/user.js' // 路由模块
import loggerMiddleware from './middleware/logger.js'; // 中间件
const app = express() // express 是个函数
app.use(express.json()) //如果前端使用的是post并且传递json 需要注册此中间件 不然是undefined
app.use('/user', User) // 注册路由模块,第一个参数自定义路由前缀
app.use(loggerMiddleware) // 注册自定义的中间件
app.get('/', (req, res) => {
console.log(req.query) //get 用query
res.send('get')
})
app.post('/create', (req, res) => {
console.log(req.body) //post用body
res.send('post')
})
app.get('/:id', (req, res) => {
console.log(req.params) //如果是动态参数用 params
res.send('get id')
})
app.listen(3000, () => console.log('Listening on port 3000'))
- src/user.js 路由模块
JavaScript
import express from 'express'
const router = express.Router() //路由模块
router.post('/login', (req, res) => {
res.send('login')
})
router.post('/register', (req, res) => {
res.send('register')
})
export default router
中间件 是处理HTTP请求和响应的函数,它位于请求和最终路由处理函数之间,可以对请求和响应进行修改、执行额外的逻辑或者执行其他任务,例如身份验证、日志记录和错误处理
中间件函数接收三个参数:req
(请求对象)、res
(响应对象)和next
(下一个中间件函数)。通过调用next()
方法,中间件可以将控制权传递给下一个中间件函数。如果中间件不调用next()
方法,请求将被中止,不会继续传递给下一个中间件或路由处理函数
防盗链
指在网页或其他网络资源中,通过直接链接到其他网站上的图片、视频或其他媒体文件,从而显示在自己的网页上。这种行为通常会给被链接的网站带来额外的带宽消耗和资源浪费,而且可能侵犯了原始网站的版权
防止盗链方式:通过HTTP引用检查、使用Referrer检查、使用访问控制列表(ACL)、使用防盗链插件或脚本、使用水印技术
- demo
JavaScript
import express from 'express';
const app = express();
const whitelist = ['localhost'];
// 防止热链中间件
const preventHotLinking = (req, res, next) => {
const referer = req.get('referer'); // 获取请求头部中的 referer 字段
if (referer) {
const { hostname } = new URL(referer); // 从 referer 中解析主机名
if (!whitelist.includes(hostname)) { // 检查主机名是否在白名单中
res.status(403).send('Forbidden'); // 如果不在白名单中,返回 403 Forbidden
return;
}
}
next(); // 如果在白名单中,继续处理下一个中间件或路由
};
app.use(preventHotLinking); // 应用防止热链中间件
app.use('/assets', express.static('static')); // 处理静态资源请求 static 为文件目录,第一参数是资源链接前缀
app.listen(3000, () => {
console.log('Listening on port 3000'); // 启动服务器,监听端口3000
});