Skip to main content

Frontend Technical Notes

info

学习并记录 General Frontend Questions

Node.js & CommonJS

1. What is require function in Node.js?

什么是 require

  • require() 是 CommonJS 的模块加载函数,在 运行时 同步读取、解析与执行目标模块(.js/.json/.node),返回其 module.exports
  • Node 会做路径解析、文件定位、编译包裹(function wrapper)、并将结果缓存在 require.cache 里(同进程二次加载走缓存)。
const fs = require('fs');                  // 内置模块
const express = require('express'); // 第三方包
const util = require('./utils'); // 本地文件
const config = require('./config.json'); // JSON 自动解析

// 导出
module.exports = { foo, bar };

2. What is buffer in Node.js?

  • 定义: Buffer 是 Node.js 提供的 二进制数据容器(类似字节数组),常用于 流(文件 I/O、TCP、加密、压缩等)。
  • 关键点: 固定长度、在 V8 堆外申请内存;与 fs、net、crypto 等 API 深度结合.
// 1. 创建 Buffer
const buf1 = Buffer.from('Hello'); // 从字符串创建
console.log(buf1.toString()); // "Hello"

// 2. 分配固定大小 Buffer
const buf2 = Buffer.alloc(5); // 分配 5 字节,默认全 0
console.log(buf2); // <Buffer 00 00 00 00 00>

// 3. Buffer 拼接
const b1 = Buffer.from('Node');
const b2 = Buffer.from('JS');
const combined = Buffer.concat([b1, b2]);
console.log(combined.toString()); // "NodeJS"

// 4. 编码/解码
const buf3 = Buffer.from('测试');
console.log(buf3.toString('utf8')); // "测试"
console.log(buf3.toString('hex')); // 十六进制形式

3. 在 Node.js 实现 Authentication & Authorization

  • 1.注册 Register
    • 接收用户信息,bcrypt.hash 加密密码,存入数据库。
  • 2.登录 Login
    • 验证邮箱+密码正确性。
    • 成功后签发两个令牌:
      • Access Token (短有效期,如 15 分钟) -> 放 subrole 信息
      • Refresh Token (长有效期,如 7 天) -> 存入 refreshTokens[] 以便后续刷新
  • 3.认证 Authentication
    • 中间件解析 Authorization: Bearer <token>
    • jwt.verify 校验有效性,挂载 req.user
  • 4.鉴权 Authorization
    • 使用中间件实现 例如 基于角色控制访问权限
    • 判断用户 role / scope 是否有权限访问
    • 若角色不匹配 → 返回 403 Forbidden
  • 5.刷新 Refresh
    • 客户端提交 refreshToken/refresh
    • 判断该 token 是否存在于 refreshTokens[]
    • 通过验证后重新签发一个新的 Access Token
    • 确保 Access Token 始终是短有效期,提高安全性
  • 6.登出 Logout
    • 客户端提交 refreshToken
    • refreshTokens[] 中删除该 token,实现 逐端登出.
    • 返回 { message: '已登出' }
// 安装依赖:npm install express bcrypt jsonwebtoken

const express = require('express');
const bcrypt = require('bcrypt'); // 用于密码哈希
const jwt = require('jsonwebtoken');

const app = express();
app.use(express.json());

const SECRET = 'my-secret-key'; // 生产环境要放在环境变量里
let users = []; // 模拟数据库
let refreshTokens = []; // 存储 Refresh Token(真实项目可放 DB/Redis)

// 1. 注册:密码哈希存储
app.post('/register', async (req, res) => {
const { email, password } = req.body;

// 对密码做哈希,10 表示 saltRounds
const hashedPassword = await bcrypt.hash(password, 10);

users.push({ email, password: hashedPassword, role: 'user' });
res.json({ message: '用户注册成功' });
});

// 2. 登录:验证凭证并签发 JWT
app.post('/login', async (req, res) => {
const { email, password } = req.body;
const user = users.find(u => u.email === email);

if (!user) return res.status(400).json({ message: '用户不存在' });

const valid = await bcrypt.compare(password, user.password);
if (!valid) return res.status(401).json({ message: '密码错误' });

// Access Token:短有效期(如 15 分钟)
const accessToken = jwt.sign(
{ sub: email, role: user.role },
SECRET,
{ expiresIn: '15m' }
);

// Refresh Token:有效期长,可撤销
const refreshToken = jwt.sign({ sub: email }, SECRET, { expiresIn: '7d' });
refreshTokens.push(refreshToken);

res.json({ accessToken, refreshToken });
});

// 3. 认证中间件:解析并验证 JWT
function authenticate(req, res, next) {
const authHeader = req.headers['authorization'];
const token = authHeader && authHeader.split(' ')[1]; // "Bearer <token>"

if (!token) return res.sendStatus(401);

jwt.verify(token, SECRET, (err, user) => {
if (err) return res.sendStatus(403); // token 过期/无效
req.user = user; // 把解码后的 payload 挂到 req 上
next();
});
}

// 4. 鉴权(授权):基于角色控制访问
function authorizeRole(role) {
return (req, res, next) => {
if (req.user.role !== role) return res.sendStatus(403);
next();
};
}

// 受保护路由:只有登录用户能访问
app.get('/profile', authenticate, (req, res) => {
res.json({ email: req.user.sub, role: req.user.role });
});

// 管理员专属路由
app.get('/admin', authenticate, authorizeRole('admin'), (req, res) => {
res.json({ message: '只有管理员能看到的内容' });
});

// 5. 刷新 Access Token
app.post('/refresh', (req, res) => {
const { token } = req.body;
if (!token || !refreshTokens.includes(token)) return res.sendStatus(403);

jwt.verify(token, SECRET, (err, user) => {
if (err) return res.sendStatus(403);
const newAccessToken = jwt.sign({ sub: user.sub, role: user.role }, SECRET, { expiresIn: '15m' });
res.json({ accessToken: newAccessToken });
});
});

// 6. 登出:移除 Refresh Token(逐端登出)
app.post('/logout', (req, res) => {
const { token } = req.body;
refreshTokens = refreshTokens.filter(t => t !== token);
res.json({ message: '已登出' });
});

app.listen(3000, () => console.log('Server running on port 3000'));

4. Babel 用来做什么

React

1. 子组件如何向父组件传值?

2. React Hooks相关问题

Redux

1. Action & Reducer 怎么用?

GraphQL

1. GraphQL