一、运行环境(前端 vs Node)

  1. 浏览器环境(前端)
    有 JS 引擎(解析执行 JS)
    有 Web API:DOM、BOM、Ajax、fetch、Canvas
    作用:渲染页面、交互、请求接口
    限制:同源策略、跨域限制
  2. Node.js 环境(后端 / 工程化)
    有 JS 引擎
    有 内置 API:fs、path、http、stream、crypto
    没有 DOM、没有 BOM、没有 window
    作用:
    写后端接口服务
    实现前端工程化(webpack、vite、打包、编译)
    运行:集成终端下运行,node 文件名.js
    快捷键:⬆⬇切换命令;tab 补全路径;esc清除命令;cls清空终端

二、path 模块

const path = require('path')
// 拼接绝对路径(最常用)
path.join(__dirname, '/a/file.txt',  '../') 
//  ../可覆盖一层

// 获取文件名(带后缀)
path.basename('/root/a/b/c.html') // c.html

// 获取文件名(不带后缀)
path.basename('/root/a/b/c.html', '.html') // c

// 获取后缀名
path.extname('index.html') // .html

// __dirname:当前文件所在文件夹的绝对路径
// __filename:当前文件的绝对路径

三、fs 文件系统模块

const fs = require('fs')
const path = require('path')
const filePath = path.join(__dirname, 'test.txt')
  1. 写入文件
fs.writeFile(filePath, '内容', (err) => {
  // 覆盖式写入
  // 只能创建文件,不能创建文件夹
  // 路径不存在会报错
})
  1. 追加写入
fs.appendFile(filePath, '追加内容\n', err => {})
  1. 读取文件
fs.readFile(filePath, 'utf8', (err, data) => {
  if (err) return console.log('读取失败')
  console.log(data)
})
//readFile 不写编码默认返回 Buffer 二进制
//写 utf8 才返回字符串

四、http 模块(创建 Web 服务器)

const http = require('http')
const server = http.createServer()

server.on('request', (req, res) => {
//监听客户端请求
  // req 请求对象
  req.url    // 请求地址
  req.method // 请求方法 GET/POST

  // res 响应对象
  //发送中文时,手动设置编码格式
  res.setHeader('Content-Type', 'text/html;charset=utf-8')
  //向客户端发送内容并结束请求
  res.end('响应内容')
  // res.end() 只能返回 字符串 / Buffer

 //动态响应
 if(req.url===''){}

})
///配置端口号,启动服务
server.listen(3000, () => {
  console.log('服务器启动:http://localhost:3000')
  //终端里ctrl c 终止监听
})

五、模块化(防止变量污染)

类型:
内置模块(导入即可)
自定义模块
第三方模块(包)(需下载)

  1. CommonJS(Node 默认,.cjs/ 无 type)
//导出
// 方式1
module.exports = { a, b }

// 方式2
exports.a = 1
exports.b = 2
//导入
const m = require('./模块')
//得到永远是module.exports指向的对象,加载模块时会直接执行模块里的代码
//exports 是 module.exports 的引用
//每个模块有个module变量,初始 module.exports={} 
//exports===module.exports
// 挂载时对象不变,直接赋值 exports = {} 会断开引用,失效,即换了一个新对象
  1. ES6 模块化(前端工程化,.mjs/package.json: “type”:“module”)
//默认导出
export default { a, b }
//按需导出
export const a = 1
export function fn(){}
import 变量名 from './模块'
import { a, fn } from './模块'

六、NPM & 包管理

  1. 初始化
    npm init -y
    生成 package.json ,记录包的清单,main是导入时包的入口
    npm i
    根据 package.json 安装所有依赖放入node_modules
  2. 安装包
    npm i 包名 // 生产依赖(dependencies)
    npm i 包名 -D // 开发依赖(devDependencies)
    npm i 包名@版本号 // 指定版本
    npm i 包名 -g //全局安装
  3. 卸载
    npm uni 包名
    npm uni 包名 -g
  4. nodemon 检测代码变化,自动重启程序
    npm i nodemon -g
    nodemon 文件名.js //运行
  5. 镜像源
    npm i nrm -g
    nrm ls
    nrm use taobao // 下载快
    nrm use npm // 发布包必须切回官方源

七、常用工具包
moment 格式化时间

const moment = require('moment')
const dt = moment().format('YYYY-MM-DD HH:mm:ss')

八、正则表达式

// 匹配所有字符(包括换行)
const reg =  /[\s\S]*/    
//压缩 
str.replace(/[\r\n]/g,'')
//提取
const r = reg.exec(str)     r[0]表示提取出的内容
// \s  空白字符
// \S  非空白字符
// \r  回车
// \n  换行
// g   全局匹配

九、IP & 端口 & 域名
域名和 IP 一一对应
127.0.0.1 = localhost(本机)
端口:标记服务
默认端口:http: 80 https: 443

十、发布包
1.编写各功能文件并导出,require('相对路径’可无后缀)导入到index.js文件,然后统一导出所有(…obj)
2.完善 package.json
name、version、main、description、keyword
3.编写 README.md
4.切换官方镜像
5.终端登录:npm login
6.发布:cd到包的根目录,npm publish
7.删除:npm unpublish 包名 --force

十一、模块加载机制

  1. 模块加载顺序(优先级从高到低)
  • 缓存优先
    模块第一次加载后会被缓存,多次 require 只执行一次,拿缓存
  • 内置模块
    fs/path/http/url 等,直接加载,不用路径
  • 第三方模块(node_modules)
    找 node_modules/包名/package.json → main 字段
    找不到 main → 找 index.js
  • 自定义模块
    必须加路径 ./ …/
    没后缀会依次尝试:.js → .json → .node
  1. 模块加载规则
    一次加载,多次缓存
    每个模块有独立模块作用域,变量不污染
    require() 得到的永远是 module.exports 指向的对象

十二、Express(封装http)

  1. 服务器
    npm i express
    //导入
    const express = require(‘express’)
    //创建
    const app = express()
    // 监听端口
    app.get(‘/api/user’, (req, res) => {
    res.send({ name: ‘zs’, age: 20 })
    res.send(req.query)// req.query查询参数 ?后的
    res.send(req.params)// req.params路径参数 :后的
    })
    //启动
    app.listen(3000, () => {
    console.log(‘服务器启动 http://localhost:3000’)
    })
  2. 路由(Router)请求与处理函数映射

创建路由文件 user.js

//导入
const express = require('express')
//创建
const router = express.Router()
//处理
router.get('/list', (req, res) => {
  res.send('用户列表')
})
//导出
module.exports = router

注册路由

const userRouter = require('./user.js')
app.use('/api', userRouter) //添加前缀
  1. 中间件(函数)
    作用:预处理请求
    语法:(req, res, next) => {next() //转发给下个中间件或路由}
    分类:
  • 应用级中间件(绑定到app上)
//全局
app.use((req, res, next) => {
  console.log('访问了')
  next() // 继续向下执行
})
//局部
app.get()
app.post()
  • 路由级中间件(绑定到router上)
    router.use()
  • 错误处理中间件
    app.use((err, req, res, next)=>{
    res.send(‘服务器错误:’ + err.message);
    } )
  • 内置中间件
//解析 JSON 格式请求体,之后才能用 req.body
app.use(express.json())
//解析表单格式
app.use(express.urlencoded({ extended: false }))
//托管静态资源
app.use(express.static('目录')) //不在url中
app.use('/url',express.static('目录')) //重复调用可托管多个,访问时按顺序查
  • 第三方中间件
    导入require+注册app.use()
  1. 跨域cors
    分简单请求和预检请求两套机制
    简单请求 :浏览器直接发真实请求 → 后端返回允许跨域响应头 → 浏览器校验通过就拿数据。
    预检请求:先发一次 OPTIONS 预检请求,询问服务器是否允许跨域、允许的方法和头。预检通过,才发送真实业务请求。

预检请求
方法:PUT / DELETE / PATCH
有自定义请求头(如 token)
Content-Type 为 application/json 等

语法:
npm i cors
const cors = require(‘cors’)
app.use(cors())

组成:

  • 浏览器机制
    自动检测请求是否跨域,跨域时自动加 Origin 请求头;
    非简单请求会自动先发 OPTIONS 预检请求。
  • 请求头(浏览器自动携带)
    Origin:当前请求来源(协议 + 域名 + 端口)
  • 响应头(后端必须配置)
    Access-Control-Allow-Origin:允许哪些源跨域
    Access-Control-Allow-Methods:允许哪些请求方法
    Access-Control-Allow-Headers:允许哪些自定义请求头
    Access-Control-Allow-Credentials:是否允许携带 Cookie
  1. session
  2. 文件上传multer
    npm i multer
    const multer = require(‘multer’)
    const upload = multer({ dest: ‘uploads/’ })
    app.post(‘/upload’, upload.single(‘file’), (req, res) => {
    res.send(‘上传成功’)
    })

顺序
先定义普通中间件,再定义路由,最后错误中间件
先定义的先执行
多个中间件,上游挂载reqh或res对象属性,供下游使用
中间件不写 next() 就卡住不往下走

  1. 示例

路由模块routes/user.js

//导入创建
const express = require('express');
const router = express.Router();

// 接口
router.get('/list', (req, res) => {
  res.send({
  status:0, //0表示成功
  msg:",
  data:req.query
  });
});
//导出
module.exports = router;

主文件

//导入创建
const express = require('express');
const app = express();
//中间件

// 引入路由
const userRouter = require('./routes/user');
// 注册路由
app.use('/api/user', userRouter);

//错误处理中间件
//启动
app.listen(3000, () => {
  console.log('服务器启动 http://localhost:3000')
})

十三、MySQL

//导入
npm i mysql
const mysql = require('mysql')
//连接
const db = mysql.createPool({
  host: 'localhost',
  user: 'root',
  password: 'root',
  database: 'testdb'
})
//导出
module.exports = db
//CRUD
//查
db.query('select * from user', (err, results) => {
  if(err) throw err
  console.log(results)
})
//条件查询
const sql = 'select * from user where id = ?';
db.query(sql, 1, (err, res)=>{});
//添加:
const sql = 'insert into user(name,age) values(?,?)';
db.query(sql, ['张三', 20], (err, res)=>{});
//修改:
const sql = 'update user set name=? where id=?';
db.query(sql, ['李四', 1], (err, res)=>{});
//删除:
const sql = 'delete from user where id=?';
db.query(sql, 1, (err, res)=>{});//id唯一且不覆盖
//全部用?占位符,占位符为1个时,可省略数组
//查 返回数组,ruselt[0]  result.length
//其余返回对象
//标记删除=更新status为1 

十四、Web 开发模式(两种)

  1. 服务端渲染(SSR)
    后端拼接 HTML → 返回浏览器
    页面在服务器生成,SEO 好,交互少时使用
    session认证
  2. 前后端分离(主流)
    前端:Vue/React 渲染页面
    后端:只提供 JSON 接口
    优点:开发高效、易维护
    页面在客户端生成,交互多时使用
    JWT 认证

十五、JWT 身份认证

  1. 作用
    替代 Cookie/Session,跨域无压力
  2. 安装
    npm i jsonwebtoken express-jwt
  3. 服务器加密生成 token,浏览器保存到本地
const jwt = require('jsonwebtoken')
const token = jwt.sign(
  { id: 1, username: 'zs' },//信息
  '加密秘钥',
  { expiresIn: '24h' }//有效期
)
  1. 浏览器发送含token请求,服务器还原并验证
const expressJwt = require('express-jwt')
app.use(expressJwt({
  secret: '加密秘钥',
  algorithms: ['HS256']
}).unless({ path: [/^\/api\/login/] })) //不需权限
  1. 错误处理
app.use((err, req, res, next) => {
  if(err.name === 'UnauthorizedError') {
    return res.send({ code: 401, msg: 'token无效' })
    //req.auth 获取用户信息
  }
})

十六、Session
服务器生成唯一 sessionId
下发到浏览器 Cookie
下次请求自动带 cookie
服务器根据 id 找到对应会话数据

npm install express-session
//创建
const session = require('express-session');
app.use(session({
  secret: 'mykey', // 加密密钥
  resave: false,
  saveUninitialized: true,
  cookie: { maxAge: 1000 * 60 * 30 } // 过期时间
}));
//判断是否正确
//存储信息
req.session.user = req.body;
req.session.islogin=true
//取session
res.send(req.session.user);
//销毁 Session(退出登录)
req.session.destroy();

校验格式joi
npm install joi express-joi-validation

十八、bcryptjs 密码加密
npm install bcryptjs
const bcrypt = require(‘bcryptjs’);
// 加密
const pwd = ‘123456’;
const salt = bcrypt.genSaltSync(10);//随机盐的长度
const hashPwd = bcrypt.hashSync(pwd, salt);
// 存 hashPwd 到数据库
// 验证
const isOk = bcrypt.compareSync(‘123456’, 数据库存的加密密码);
if(isOk){
// 登录成功
}

Logo

openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构

更多推荐