- Node.js là gì? Điểm khác biệt với JavaScript trên trình duyệt?
Node.js là runtime cho phép chạy JavaScript ngoài trình duyệt, ở phía server hoặc công cụ dòng lệnh, được xây dựng trên V8 engine của Chrome và thư viện libuv để xử lý I/O bất đồng bộ. Khác với JavaScript trên trình duyệt vốn bị…
- V8 engine là gì? Vai trò của nó trong Node.js?
V8 là JavaScript engine mã nguồn mở của Google, viết bằng C++, dùng trong Chrome và là lõi thực thi JavaScript trong Node.js. V8 biên dịch JavaScript thành native machine code bằng JIT (Just-In-Time) compilation, giúp code chạy nhanh gần bằng C++. Hãy nghĩ V8…
- Event-driven architecture trong Node.js nghĩa là gì?
Event-driven architecture là mô hình mà luồng điều khiển do sự kiện quyết định thay vì chạy tuần tự từ trên xuống. Trong Node.js, bạn đăng ký hàm xử lý cho một sự kiện và runtime sẽ gọi hàm đó khi sự kiện xảy ra,…
- Non-blocking I/O trong Node.js là gì? Tại sao quan trọng?
Non-blocking I/O là mô hình mà Node.js gửi thao tác I/O (đọc ghi file, query DB, gọi HTTP…) xuống kernel hoặc thread pool rồi trả quyền điều khiển về event loop ngay lập tức, không chờ kết quả. Khi I/O xong, callback được đẩy vào…
- npm là gì? Phân biệt npm install, npm install --save-dev?
dependencies cho production; devDependencies cho build/test tools (không được bundle vào production) — npm ci trong CI/CD đảm bảo deterministic install từ lock file. npm (Node Package Manager) là công cụ quản lý packages mặc định đi kèm Node.js, với registry hơn 2 triệu packages.…
- package.json là gì? Các trường quan trọng trong package.json?
package.json manifest chứa scripts (lifecycle hooks), dependencies/devDependencies, engines (Node version), exports (conditional entry points), và workspaces (monorepo). package.json là manifest file của Node.js project. scripts hỗ trợ lifecycle hooks: preinstall/postinstall chạy trước/sau npm install, prebuild/postbuild bao quanh build — dùng để codegen, copy assets. engines:…
- package-lock.json là gì? Tại sao nên commit file này?
package-lock.json lưu exact versions + integrity hashes (sha512) của tất cả packages kể cả transitive dependencies — đảm bảo install reproducible trên mọi máy/CI. npm install cập nhật lock file nếu package.json thay đổi; npm ci (clean install) xoá nodemodules rồi install chính xác từ…
- CommonJS modules (require/module.exports) và ES Modules (import/export) trong Node.js khác nhau như thế nào?
CommonJS (CJS): require() load đồng bộ và blocking, nên gọi được ở bất cứ đâu — kể cả trong if hay trong function. module.exports gán được bất kỳ giá trị gì, đổi lại là không tree-shaking được. ESM: import bắt buộc ở top-level để bundler…
- process object trong Node.js cung cấp những gì?
process là global object không cần require. process.env: chứa environment variables — KHÔNG bao giờ log toàn bộ process.env vì chứa secrets; validate với zod/envalid ngay startup để fail fast nếu thiếu. process.argv: array [nodePath, scriptPath, ...userArgs] — dùng yargs hoặc commander để parse thay…
- Sự khác biệt giữa __dirname và __filename trong Node.js?
dirname là đường dẫn tuyệt đối đến thư mục chứa file đang chạy, filename là đường dẫn đến chính file đó. Cả hai resolve từ vị trí file, không phải từ process.cwd(). Trong ES Modules (file .mjs hoặc type: module trong package.json) hai biến này…
- Event loop trong Node.js hoạt động như thế nào?
Event loop là vòng lặp chạy liên tục, xử lý callback qua sáu phase: 1. Timers — chạy callback của setTimeout/setInterval đã đến hạn. 2. Pending callbacks — lỗi I/O còn tồn từ vòng trước. 3. Idle/prepare — dùng nội bộ. 4. Poll — nhận…
- Sự khác biệt giữa setTimeout(fn, 0) và setImmediate() là gì?
setTimeout(fn, 0) thực ra là setTimeout(fn, 1) tối thiểu, chạy ở timers phase khi timer đã hết hạn. setImmediate() chạy ở check phase, ngay sau poll phase. Ngoài I/O context (ví dụ chạy thẳng trong main script) thứ tự giữa hai cái không đảm bảo…
- process.nextTick() khác setImmediate() như thế nào?
- Callback hell là gì? Cách giải quyết?
Callback hell (pyramid of doom) là chuỗi callback lồng nhau nhiều tầng, error handling lặp lại ở từng tầng và logic khó theo dõi: Promise chaining làm phẳng bớt nhưng vẫn vướng khi cần truyền nhiều giá trị qua các bước: async/await đọc như code…
- Promise trong Node.js hoạt động như thế nào? Các states của Promise?
Promise là object đại diện cho async operation, có 3 states không thể revert: pending → fulfilled/rejected. Microtask queue: .then() callbacks được đặt vào microtask queue (ưu tiên cao hơn setTimeout), chạy sau synchronous code nhưng trước event loop phases. Static methods quan trọng: Promise.all([p1,p2])…
- async/await trong Node.js là gì? Lợi ích so với Promise chains?
async/await là syntactic sugar trên Promise — async function luôn trả về Promise, còn await tạm dừng thực thi của chính function đó (không block thread) cho đến khi Promise settle. Try/catch bắt rejected Promise như exception thường: Chạy song song hay tuần tự quyết…
- Streams trong Node.js là gì? Có những loại stream nào?
- Buffer trong Node.js là gì? Khi nào cần dùng?
Buffer là class built-in xử lý binary data — vùng nhớ raw bytes nằm ngoài V8 heap. JavaScript thuần không có kiểu dữ liệu binary, Buffer lấp đầy khoảng trống này cho Node.js. Cần dùng khi: đọc file binary (ảnh, PDF, executable), xử lý network…
- Libuv là gì? Vai trò trong Node.js?
- Cách tạo HTTP server với module http trong Node.js?
Module http là built-in, không cần cài thêm: - req chứa method, url, headers và là Readable stream — đọc body qua req.on('data', chunk = ...). - res là Writable stream — phải gọi res.end() để kết thúc, không thì client treo mãi. Thực tế…
- Express.js là gì? Tại sao phổ biến trong Node.js ecosystem?
Express là web framework minimal cho Node.js, cung cấp routing và middleware system mà không áp đặt cấu trúc dự án. Phổ biến nhất trong Node.js ecosystem vì: API cực đơn giản (app.get('/users', handler)), middleware pipeline linh hoạt cho phép compose nhiều concerns (auth, logging,…
- Middleware trong Express là gì? Cách hoạt động?
Middleware là function có signature (req, res, next), chạy tuần tự đúng theo thứ tự đăng ký — và thứ tự ở đây là tuyệt đối. - App-level: app.use(helmet()) áp cho toàn bộ app. - Router-level: router.use(authMiddleware) chỉ áp cho nhóm route đó. - Error-handling:…
- Router trong Express là gì? Cách tổ chức routes?
express.Router() tạo một mini-app có route và middleware riêng — đây là cách chính để tổ chức code theo feature. - Nested router: adminRouter.use('/users', adminUserRouter) để lồng sâu hơn. - Versioned API: app.use('/api/v1', v1Router) và app.use('/api/v2', v2Router) — hai version độc lập hoàn toàn nên…
- REST API trong Express: cách định nghĩa các HTTP methods?
Express map trực tiếp tới HTTP methods với semantics rõ ràng: GET (idempotent, safe — chỉ đọc, không side effects), POST (không idempotent — tạo resource mới, mỗi call tạo record mới), PUT (idempotent — replace toàn bộ resource, gửi thiếu field thì field đó…
- Error handling middleware trong Express hoạt động như thế nào?
Error handling middleware có 4 tham số (err, req, res, next) và phải đăng ký CUỐI CÙNG, sau tất cả routes. - AppError tách operational error (404, validation fail — lường trước được) khỏi programming error (null reference — bug thật). - Express 5 tự…
- CORS trong Express: cách cấu hình cho phép cross-origin requests?
CORS là cơ chế trình duyệt bảo vệ user — server phải opt-in mới cho phép request cross-origin. Trình duyệt tự gửi request OPTIONS trước nếu là preflighted request (method ngoài GET/POST/HEAD, hoặc header không đơn giản như Content-Type: application/json); simple request (GET với header…
- express.json() và express.urlencoded() middleware dùng để làm gì?
express.json() parse Content-Type: application/json thành object req.body — có sẵn từ Express 4.16+, không cần cài body-parser nữa. - express.urlencoded({ extended: true }) parse form HTML (application/x-www-form-urlencoded). extended: true dùng thư viện qs nên nhận được object lồng nhau; extended: false dùng querystring, chỉ phẳng.…
- Rate limiting trong Express là gì? Cách implement?
Rate limiting bảo vệ API khỏi spam, brute-force và DDoS. Fixed window đếm request trong khung cố định (0:00-0:15) — dễ lách bằng cách dồn burst vào cuối khung cũ rồi đầu khung mới. Sliding window trượt theo thời gian thực nên chính xác hơn,…
- Sự khác biệt giữa Express 4 và Express 5 là gì?
- JWT (JSON Web Token) là gì? Cấu trúc của JWT?
JWT là chuẩn mở (RFC 7519) để truyền thông tin dưới dạng JSON có ký số bảo đảm toàn vẹn. Chuỗi token gồm ba phần ngăn bởi dấu chấm, mỗi phần mã hoá base64url: - Header — { alg: 'HS256', typ: 'JWT' } - Payload…
- Cách implement JWT authentication trong Express API?
Luồng đầy đủ: POST /login xác thực credentials, ký hai token, trả access token trong response body và refresh token trong httpOnly cookie. Middleware xác thực đọc token từ header và bắt buộc chốt thuật toán: - httpOnly cookie chặn được XSS đọc token (nhưng…
- bcrypt là gì? Cách dùng để hash password?
bcrypt sinh ra để hash password, khác hẳn SHA-256/MD5 vốn tối ưu cho nhanh: GPU hash SHA-256 được 10 tỷ lần mỗi giây, còn bcrypt cost=12 chỉ chừng 250 lần mỗi giây. - Adaptive cost factor: mỗi nấc saltRounds làm thời gian tăng gấp đôi…
- Access token và Refresh token khác nhau như thế nào?
- Clustering trong Node.js là gì? Tại sao cần thiết?
- Worker Threads trong Node.js là gì? Khác gì với Cluster?
- Microservices architecture với Node.js: ưu và nhược điểm?
- Caching trong Node.js API: các chiến lược phổ biến?
Cache-aside (lazy loading) là pattern phổ biến nhất: đọc cache → miss → truy vấn DB → ghi cache → trả về. Hai biến thể còn lại đánh đổi khác nhau: write-through ghi cache và DB cùng lúc — data luôn fresh nhưng write chậm…
- Cách xử lý unhandled Promise rejections trong Node.js?
Node.js 14 trở về trước chỉ in cảnh báo rồi chạy tiếp — lỗi bị nuốt mất mà không ai hay. Từ Node.js 15 mặc định process crash với exit code 1, đây là breaking change. Thứ tự xử lý đúng: try/catch trong async function…
- fs module trong Node.js: fs.readFile vs fs.createReadStream khác nhau như thế nào?
fs.readFile() load toàn bộ file vào RAM trước khi callback — file 100MB chiếm ít nhất 100MB heap; 100 concurrent requests = 10GB RAM, dễ OOM crash. fs.createReadStream() đọc theo chunks (default highWaterMark 64KB) — file 100MB chỉ dùng ~64KB RAM bất kể bao nhiêu…
- Sự khác biệt giữa fs.readFile và fs.readFileSync là gì?
readFileSync blocking — chặn đứng event loop cho đến khi OS trả data, không xử lý request nào khác trong thời gian đó. readFile non-blocking — gửi I/O request đến libuv thread pool, event loop rảnh để xử lý request khác. Impact thực tế: readFileSync…
- Environment variables trong Node.js: cách dùng và tại sao quan trọng?
Environment variable tách config khỏi code theo 12-factor app: config là bất cứ thứ gì đổi giữa các môi trường (dev/staging/prod). require('dotenv').config() nạp .env vào process.env và KHÔNG ghi đè biến đã có — production inject thẳng qua Docker/K8s/CI, không cần file .env. dotenv-safe đối…
- Event loop blocking trong Node.js là gì? Làm thế nào để tránh?
- Backpressure trong Node.js streams là gì? Tại sao quan trọng?
- Cách debug Node.js application?
Breakpoint debugging: node --inspect app.js mở debugger ở cổng 9229, vào chrome://inspect để attach. --inspect-brk dừng ngay dòng đầu — dùng khi cần debug đoạn khởi tạo. - Memory profiling: DevTools → Memory → Heap Snapshot, so sánh hai snapshot để tìm rò rỉ; cột…
- Event Emitter trong Node.js là gì? Cách dùng?
- Các lỗ hổng bảo mật phổ biến trong Node.js API và cách phòng tránh?
Bảy lỗ hổng hay gặp nhất trong một Node.js API, kèm cách bịt: - SQL injection (OWASP A03): db.query('SELECT FROM users WHERE id = ' + req.params.id) — attacker truyền 1 OR 1=1 là dump sạch DB. Sửa bằng parameterized query db.query('SELECT FROM users WHERE…
- Graceful shutdown trong Node.js là gì? Tại sao quan trọng?
- Cách viết unit tests cho Node.js API với Jest?
Test pyramid cho một Node.js API: unit test (logic service/utils) → integration test (controller + DB thật) → e2e test (HTTP đầy đủ). Controller test bằng supertest, không cần start server vì supertest inject request thẳng vào app: Service thì mock tầng DB để test…
- PM2 là gì? Tại sao dùng PM2 trong production?
- Node.js là gì? Tại sao dùng cho backend?
Node.js là runtime JavaScript trên server, dùng V8 engine. Ưu điểm: non-blocking I/O xử lý nhiều requests đồng thời, cùng ngôn ngữ với frontend (JS) nên team dùng chung tooling và type definitions, npm ecosystem khổng lồ với hàng triệu packages, fit cho real-time apps…
- REST API là gì? Thiết kế REST API cần tuân thủ những nguyên tắc nào?
REST (Representational State Transfer) là kiến trúc thiết kế API dựa trên HTTP, trong đó mỗi URL đại diện cho một resource (tài nguyên). Nguyên tắc quan trọng: dùng danh từ số nhiều cho endpoints (/users, /products), dùng đúng HTTP methods — GET lấy dữ…
- Cách handle file upload trong Node.js?
Để xử lý file upload trong Express, thư viện phổ biến nhất là multer hoạt động như một middleware, cấu hình bằng const upload = multer({ dest: 'uploads/' }) rồi gắn vào route cụ thể như app.post('/upload', upload.single('file'), handler). Khi nhận file cần validate kỹ…
- Streams trong Node.js là gì? Tại sao cần dùng Streams thay vì đọc toàn bộ file?
Streams xử lý data theo từng phần nhỏ (chunks) thay vì load toàn bộ vào memory — rất quan trọng khi xử lý file lớn (CSV hàng GB, video). Có 4 loại: Readable (đọc data, ví dụ fs.createReadStream), Writable (ghi data, ví dụ fs.createWriteStream), Duplex…
- Process.env và dotenv hoạt động thế nào?
process.env là object chứa tất cả environment variables của hệ điều hành mà Node.js process có thể truy cập, ví dụ process.env.DATABASEURL để lấy connection string. Thư viện dotenv đọc file .env ở root project và inject các biến vào process.env lúc khởi động app,…
- Validation input trong Express dùng gì?
Zod là lựa chọn tốt nhất cho Express + TS: schema-first, type-safe, safeParse trả structured errors. Alternatives: Joi, Yup, class-validator. Validate ở layer đầu tiên — trước bất kỳ business logic nào.
- Caching strategy cho Node.js API?
- Error handling strategy cho production Node.js?
- Logging best practices cho Node.js production?
Logging trong production cần có cấu trúc và chiến lược rõ ràng để debug hiệu quả khi có sự cố. Nên dùng Pino (nhanh nhất, gấp 5 lần Winston) hoặc Winston (linh hoạt hơn, nhiều transports), và format log dưới dạng JSON thay vì text…
- Websocket với Socket.io trong Node.js dùng thế nào?
Socket.io wraps WebSocket với automatic reconnection, rooms, và namespace support. Rooms cho group chat, namespaces cho tách concerns. Reconnection tự động.
- Microservices communication patterns?
- Node.js single-threaded. Tại sao vẫn handle multiple request? Event loop explain.
Node.js chạy JavaScript trên một thread duy nhất, nhưng vẫn xử lý được nhiều request đồng thời nhờ cơ chế non-blocking I/O và event loop. Khi có tác vụ I/O (đọc file, gọi database, HTTP request), Node.js giao cho libuv xử lý trong thread pool…
- Callback vs Promise vs async/await. Cách handle error trong mỗi?
Callback là cách xử lý bất đồng bộ đầu tiên trong JavaScript, nhưng dễ dẫn đến callback hell khi lồng nhiều tầng và khó xử lý lỗi vì phải kiểm tra error ở mỗi callback. Promise cải thiện bằng cách dùng .then() để chain và…
- Environment variable trong Node.js. Tại sao cần? .env file?
Environment variable dùng để lưu trữ cấu hình thay đổi theo từng môi trường (development, staging, production) như database URL, API key, port number, mà không cần thay đổi code. File .env chứa các biến này cho môi trường phát triển local, và package dotenv…
- Child process trong Node.js: `spawn()`, `fork()` và `exec()` khác nhau thế nào?
Cả ba đều thuộc module childprocess, tạo tiến trình con để chạy việc ngoài event loop, nhưng khác về cách nhận kết quả: - spawn(cmd, args): chạy lệnh và trả về stream stdout/stderr. Không buffer toàn bộ output → hợp với dữ liệu lớn hoặc…
- Reactor pattern trong Node.js là gì và nó là nền tảng cho event loop ra sao?
- Nhược điểm của Node.js là gì? Khi nào KHÔNG nên dùng?
Điểm mạnh của Node (một luồng + event loop) cũng là điểm yếu: mọi request chia sẻ một luồng chạy JS. - Tác vụ CPU-bound làm nghẽn event loop: một vòng lặp nặng hay hàm đồng bộ tốn CPU sẽ chặn luồng, khiến mọi request…
- Module `crypto` của Node.js cung cấp những gì? (hashing, HMAC, cipher)
Module built-in crypto bọc OpenSSL, gom các nhóm primitive mật mã: - Hashing — createHash('sha256'): băm một chiều, không khoá. Dùng cho checksum/toàn vẹn dữ liệu. - HMAC — createHmac('sha256', key): băm có khoá bí mật, để xác thực rằng dữ liệu do bên biết…
- Piping stream bằng `.pipe()` trong Node.js là gì và liên hệ với backpressure ra sao?
- Quản lý session trong Node.js: `express-session` khác JWT thế nào?
Hai cách giữ trạng thái đăng nhập, khác nhau ở chỗ state nằm đâu: express-session (stateful, server-side) - Server lưu dữ liệu session; client chỉ giữ một session id trong cookie. - Cần một store (Redis/DB) để scale ngang nhiều instance — không nên để…
- `Buffer.alloc`, `Buffer.allocUnsafe` và `Buffer.from` khác nhau thế nào? Vì sao `allocUnsafe` bị coi là rủi ro?
- Buffer.alloc(n) cấp phát n byte và ghi 0 toàn bộ vùng nhớ. - Buffer.allocUnsafe(n) cấp phát n byte nhưng không khởi tạo — nội dung là phần bộ nhớ vừa được giải phóng trước đó, có thể còn dữ liệu cũ của tiến trình.…
- Gặp lỗi `ERR_REQUIRE_ESM` hoặc `Cannot use import statement outside a module` thì nguyên nhân là gì và xử lý ra sao?
Cả hai lỗi đều là lệch hệ module: file đang được Node hiểu theo một hệ (CommonJS hoặc ESM) nhưng code viết theo hệ kia. - Cannot use import statement outside a module: file bị coi là CommonJS nhưng dùng import. - ERRREQUIREESM: code CommonJS…
- Log production hiện `MaxListenersExceededWarning: Possible EventEmitter memory leak detected. 11 listeners added` — nghĩa là gì và sửa thế nào?
Node cảnh báo khi một EventEmitter có hơn 10 listener cho cùng một sự kiện (ngưỡng mặc định). Đây là cảnh báo, không phải lỗi — nhưng nó thường chỉ đúng vào một rò rỉ thật. Nguyên nhân điển hình: đăng ký listener bên trong…
- Thread pool của libuv là gì? API nào của Node dùng nó, API nào không? `UV_THREADPOOL_SIZE` ảnh hưởng ra sao?
Node chỉ chạy JavaScript trên một thread, nhưng libuv giữ một thread pool để làm những việc hệ điều hành không cung cấp API bất đồng bộ tốt. Mặc định pool có 4 thread, chỉnh qua biến môi trường UVTHREADPOOLSIZE (tối đa 1024, phải đặt…
- Vì sao nên dùng `stream.pipeline()` thay vì nối `.pipe()`?
.pipe() chỉ làm một việc: chuyển dữ liệu và xử lý đúng backpressure. Nó không lan truyền lỗi và không dọn dẹp. Khi một stream trong chuỗi a.pipe(b).pipe(c) phát error: - Các stream còn lại không bị destroy → file descriptor, socket, buffer vẫn treo.…
- Cần import file CSV 2GB vào database. Em thiết kế luồng thế nào để không hết bộ nhớ?
Không đọc cả file vào RAM. Dựng một pipeline đọc → parse → gom lô → ghi, để backpressure tự điều tiết tốc độ theo DB. Vì sao không hết bộ nhớ: writer.write chỉ gọi cb() sau khi DB ghi xong. Chừng nào chưa gọi,…
- `AsyncLocalStorage` giải quyết vấn đề gì? Dùng nó để gắn request id vào log như thế nào?
Nó giải quyết bài toán truyền context xuyên qua chuỗi bất đồng bộ mà không phải thêm tham số vào mọi hàm. Trong Node không có thread-local storage; AsyncLocalStorage là bản tương đương cho môi trường async: một store gắn với "vùng chạy" và tự…
- Service Node trên Kubernetes vẫn trả 502 mỗi lần rolling update dù đã bắt `SIGTERM` và gọi `server.close()`. Nguyên nhân và cách khắc phục?
Có hai nguyên nhân riêng biệt, thường xảy ra cùng lúc. 1. Đóng quá sớm so với việc cập nhật routing. Khi pod bị xoá, Kubernetes gửi SIGTERM và gỡ pod khỏi Endpoints song song, không tuần tự. Các kube-proxy/ingress cần thời gian để cập…
- Từ Node 15, promise bị reject mà không ai bắt sẽ gây chuyện gì? Nên xử lý `unhandledRejection` và `uncaughtException` thế nào trong production?
Từ Node 15, mặc định của --unhandled-rejections đổi từ warn sang throw: nếu không có handler unhandledRejection, rejection không bắt được sẽ nổi lên thành uncaught exception và làm chết tiến trình. Trước đó nó chỉ in cảnh báo và app chạy tiếp — đây…
- Một endpoint xử lý CPU nặng (resize ảnh, xuất Excel 200k dòng) làm treo toàn bộ API. Em cân nhắc `worker_threads`, `cluster`, `child_process` và job queue thế nào?
- Service Node có RSS tăng dần rồi bị OOM sau vài ngày. Em điều tra bằng heap snapshot ra sao?
- Truyền dữ liệu giữa main thread và `worker_threads` tốn kém ra sao? `transferList` và `SharedArrayBuffer` khác gì nhau?
- Thứ tự đăng ký middleware trong Express quan trọng thế nào? Vì sao middleware khai báo sau route lại không chạy?
Express xếp mọi app.use() và route handler vào một stack theo đúng thứ tự khai báo, rồi duyệt từ trên xuống cho mỗi request. Một middleware chỉ chạy nếu request đi tới được vị trí của nó. Hai trường hợp làm luồng xử lý dừng…
- Phân biệt `next()`, `next(err)` và `next('route')` trong Express?
Ba cách gọi next cho ba luồng khác nhau: - next() — chuyển sang middleware/handler kế tiếp trong stack, luồng bình thường. - next(err) — truyền bất kỳ giá trị nào khác chuỗi 'route' sẽ nhảy thẳng tới error-handling middleware (loại 4 tham số), bỏ…
- Vì sao `express.json()` không đọc được file upload? Xử lý `multipart/form-data` thế nào?
express.json() chỉ parse body có Content-Type: application/json; express.urlencoded() chỉ parse application/x-www-form-urlencoded. Form có file được browser gửi dưới dạng multipart/form-data — body bị chia thành nhiều phần ngăn bởi chuỗi boundary, mỗi phần có header riêng. Không parser nào trong hai cái trên hiểu định…
- Vì sao error-handling middleware trong Express bắt buộc phải khai báo đủ 4 tham số?
Express nhận diện error handler hoàn toàn dựa vào số tham số của hàm (fn.length === 4). Nếu bạn viết (err, req, res) — bỏ next — Express coi đó là middleware thường với err được hiểu là req, và lỗi sẽ rơi xuống default…
- Trong Express 4, handler `async` ném lỗi thì error middleware không bắt được — vì sao? Express 5 thay đổi gì?
Express 4 chỉ bọc try/catch quanh lời gọi handler đồng bộ. Một hàm async trả về Promise ngay lập tức, lỗi xảy ra sau đó nằm ở dạng rejected promise — Express không biết tới, request treo cho tới timeout và Node ghi UnhandledPromiseRejection. Ba…
- Lỗi `ERR_HTTP_HEADERS_SENT` — "Cannot set headers after they are sent to the client" — do đâu và sửa thế nào?
Khi headers đã được flush xuống client, Node cấm sửa header hoặc bắt đầu một response thứ hai trên cùng request. Bản chất lỗi luôn là gửi response hai lần cho một request. Ba mẫu code hay gây ra: Cách sửa: - Luôn return res.json(...)…
- Router lồng nhau trong Express: vì sao router con đọc `req.params.userId` ra `undefined`? Sửa thế nào?
- Thiết kế luồng upload file dung lượng lớn (hàng GB) trong Node.js sao cho không tràn RAM?