Menu

req.params, req.query và req.body trong Express

req.params chứa các phần có tên trong đường dẫn (/users/:id), req.query chứa query string (?sort=new), còn req.body chứa body của request đã được parse, và nó là undefined cho đến khi bạn thêm một body parser như express.json().

Trang này có trình soạn thảo chạy trực tiếp. Sửa, chạy và xem đầu ra ngay lập tức.

Trong Express, req.params chứa giá trị của các đoạn có tên trong đường dẫn route (/users/:id cho bạn req.params.id), req.query chứa query string sau dấu ? (/search?q=node cho bạn req.query.q), còn req.body chứa dữ liệu gửi trong body của request. req.params và req.query có giá trị ở mọi request, nhưng req.body vẫn là undefined cho đến khi một body parser như app.use(express.json()) đọc nó. Giá trị trong params và query luôn là chuỗi.

Request đầu tiên trả về {"params":{"userId":"7"},"query":{"sort":"new","limit":"2"}}. Chú ý dấu ngoặc kép: 7 và 2 là chuỗi, nên hãy chuyển chúng bằng Number() trước khi tính toán hoặc so sánh với số. Giờ đổi phương thức sang POST, giữ đường dẫn /users/7/posts và gửi body {"title": "Hello", "draft": true}: câu trả lời là 201 với "body":{"title":"Hello","draft":true}, trong đó true là boolean thật vì nó đến từ JSON.

req.params, req.query và req.body khác nhau thế nào

req.paramsreq.queryreq.body
Lấy từĐường dẫn, /users/:idQuery string, ?sort=newBody của request
Ví dụ URL hoặc body/users/7/users?sort=new{"name": "Ada"}
Giá trị{ id: '7' }{ sort: 'new' }{ name: 'Ada' }
KiểuChuỗiChuỗi và mảng chuỗiTùy nội dung JSON
Cần thiết lậpMột :name trong routeKhông cần gìapp.use(express.json())
Dùng đểChọn tài nguyên nàoLọc, sắp xếp, phân trangDữ liệu để tạo hoặc cập nhật

Một route có thể có nhiều tham số, và mỗi tên trở thành một khóa của req.params: /teams/:teamId/members/:memberId cho bạn cả hai id. Dấu gạch nối hoặc dấu chấm cũng tách các tham số, nên /flights/:from-:to biến /flights/LAX-SFO thành { from: 'LAX', to: 'SFO' }.

req.query với khóa lặp lại và khóa bị thiếu

Một khóa xuất hiện hai lần sẽ thành mảng, còn khóa bị thiếu là undefined, nên hãy cho các tùy chọn một giá trị mặc định:

Câu trả lời là {"page":1,"tags":["red","sale"],"raw":{"tag":["red","sale"]}}. Gửi GET /products?tag=red&page=3 thì tags vẫn là mảng, ["red"], vì [].concat() biến một chuỗi hay một mảng đều thành mảng. Express 5 parse query string bằng bộ parser đơn giản của Node, nên ?filter[size]=m cho ra khóa "filter[size]", không phải object lồng nhau; Express 4 thì tạo object lồng nhau.

req.body cần express.json()

Node đưa body đến dưới dạng một luồng byte. express.json() đọc, parse và gán req.body, nhưng chỉ khi request có Content-Type: application/json. Form HTML gửi application/x-www-form-urlencoded, loại này cần express.urlencoded().

Gửi POST /signup với body {"email": "ada@example.com"} và bạn nhận 201 với {"email":"ada@example.com","name":"anonymous"}. Gửi body rỗng thì bạn nhận 400. Phần ?? {} rất quan trọng: thiếu nó, việc destructuring undefined sẽ ném TypeError với mọi request không có body JSON. Để kiểm tra thật sự cấu trúc và kiểu dữ liệu, hãy dùng một thư viện schema như zod.

req.headers và req.get()

req.headers là một object chứa mọi header của request, với tên viết thường. req.get(name) đọc một header và không phân biệt hoa thường, nên req.get('Content-Type') và req.get('content-type') trả về cùng một giá trị. Một vài thuộc tính khác bạn sẽ dùng đến:

path là /whoami còn originalUrl là /whoami?debug=1. Thêm header Authorization: Bearer abc vào thanh request rồi gửi lại: token trở thành "Bearer abc". Bên trong một router được gắn bằng app.use('/api', router), req.path mất tiền tố /api còn req.originalUrl vẫn giữ nó (routing trong Express giải thích cách gắn router).

Lỗi thường gặp

Đọc req.body trong request GET. Trình duyệt và hầu hết client không gửi body với GET. Hãy đặt các tùy chọn của GET vào query string.

Kiểm tra cờ trong query theo kiểu truthy. ?admin=false cho ra chuỗi 'false', là giá trị truthy, nên if (req.query.admin) vẫn đúng. Hãy so sánh chuỗi: req.query.admin === 'true'.

Gửi JSON mà không có header. Client gửi JSON với kiểu text/plain sẽ nhận req.body === undefined. Hãy đặt Content-Type: application/json ở phía client.

Câu hỏi thường gặp

Làm sao lấy địa chỉ IP của client trong Express?

Đọc req.ip. Khi chạy sau proxy hoặc load balancer, giá trị này là địa chỉ của proxy cho đến khi bạn đặt app.set('trust proxy', 1), lúc đó Express đọc header X-Forwarded-For thay thế.

Làm sao lấy URL đầy đủ của một request trong Express?

req.originalUrl là đường dẫn cộng với query string, đúng như client đã gửi. Ghép URL tuyệt đối bằng `${req.protocol}://${req.get('host')}${req.originalUrl}`.

Làm sao xử lý upload tệp trong Express?

Tệp upload được gửi dưới dạng multipart/form-data, mà express.json() và express.urlencoded() không parse. Hãy dùng một package như multer, nó đưa tệp vào req.file hoặc req.files và các trường còn lại vào req.body.

Làm sao đọc cookie từ request?

Header gốc nằm trong req.get('cookie'). Để có một object trong req.cookies, cài package cookie-parser và thêm app.use(cookieParser()).

Hình minh họa các ngôn ngữ lập trình của Coddy

Học lập trình cùng Coddy

Bắt đầu