Khi chúng ta muốn lưu trữ một đối tượng JavaScript thành một chuỗi JSON, chúng ta sử dụng hàm JSON.stringify(). Hàm này sẽ chuyển đổi đối tượng thành một chuỗi JSON. Ví dụ, trong đoạn mã trên, JSON.stringify(obj) sẽ chuyển đổi đối tượng obj thành một chuỗi JSON. Điều này được thực hiện bởi hàm JSON.stringify(), vì vậy nó chịu trách nhiệm cho quá trình serial hóa. Sau đó, chúng ta sử dụng hàm JSON.parse() để chuyển đổi chuỗi JSON trở lại thành một đối tượng JavaScript. Điều này được thực hiện bởi hàm JSON.parse(), vì vậy nó chịu trách nhiệm cho quá trình giải mã. Các câu lệnh console.log() chỉ đơn giản là in ra kết quả, chúng không chịu trách nhiệm cho quá trình serial hóa hay giải mã.
Ngân hàng câu hỏi môn Server-Side development with NodeJS, Express, and MongoDB
Ôn luyện SDN302 – Phát triển Server-Side với Node.js, Express và MongoDB: ngân hàng câu hỏi trắc nghiệm có đáp án và giải thích chi tiết, luyện thi cuối kỳ hiệu quả. Nội dung bao quát Node.js, npm, Event Loop bất đồng bộ, HTTP/HTTPS, Express.js, middleware, Express Generator, RESTful API, MongoDB & Mongoose, Mongoose Population, xác thực Passport/JWT, session & cookie, mã hoá bcrypt, upload/download file với Multer, CORS, OAuth và template EJS/Handlebars. Môn 3 tín chỉ tại FPT University, tiên quyết DBI202 và FER202.
Bắt đầu một phiên học theo môn
Tiến độ của bạn sẽ luôn được tính toán và đồng bộ trực tiếp theo tổng số lượng câu hỏi mới nhất của môn học này.
Bạn cần đăng nhập để bắt đầu học từ ngân hàng câu hỏi và lưu tiến độ theo môn.
Đang tải phân bố độ khó.
Một nhà phát triển có thể chọn một cơ sở dữ liệu NoSQL như MongoDB thay vì cơ sở dữ liệu SQL để ứng dụng phân tích thời gian thực vì một số lý do. Cơ sở dữ liệu NoSQL cho phép sử dụng cấu trúc dữ liệu linh hoạt, phù hợp với dữ liệu thay đổi nhanh chóng. Điều này giúp giảm thiểu thời gian và công sức khi thiết kế và triển khai cơ sở dữ liệu. Ngoài ra, cơ sở dữ liệu NoSQL thường có khả năng mở rộng tốt hơn, cho phép xử lý lượng dữ liệu lớn và nhanh chóng. Điều này đặc biệt quan trọng trong ứng dụng phân tích thời gian thực, nơi dữ liệu được cập nhật liên tục và cần được xử lý nhanh chóng để cung cấp thông tin chính xác và kịp thời.
Để tạo một server trong Node.js, chúng ta cần sử dụng một module được tích hợp sẵn. Trong các lựa chọn trên, module nào được sử dụng để tạo server?
Sử dụng async/await trong mã nguồn này mang lại nhiều lợi ích. Trước hết, nó giúp mã nguồn trở nên dễ đọc và dễ hiểu hơn. Điều này là do async/await cho phép chúng ta viết mã nguồn theo trình tự thời gian thực, giống như viết mã nguồn đồng bộ. Điều này giúp giảm thiểu sự phức tạp và khó hiểu của mã nguồn. Ngoài ra, async/await cũng giúp đơn giản hóa việc xử lý lỗi bằng cách sử dụng khối try/catch. Khi sử dụng async/await, chúng ta có thể dễ dàng bắt và xử lý lỗi bằng cách sử dụng khối try/catch, thay vì phải sử dụng các hàm callback phức tạp. Điều này giúp giảm thiểu sự phức tạp và khó hiểu của mã nguồn. Tuy nhiên, async/await không loại bỏ hoàn toàn nhu cầu sử dụng hàm callback. Trong một số trường hợp, chúng ta vẫn cần sử dụng hàm callback để xử lý các tác vụ phức tạp. Vì vậy, async/await không phải là giải pháp hoàn hảo, nhưng nó là một công cụ mạnh mẽ giúp chúng ta viết mã nguồn dễ đọc, dễ hiểu và dễ bảo trì.
Trong Handlebars template, {{greeting}} được hiểu là biểu thức mẫu (template expression). Khi bạn truyền dữ liệu { greeting: 'Hi' } vào template, biểu thức mẫu sẽ được thay thế bằng giá trị thực tế. Trong trường hợp này, {{greeting}} sẽ được thay thế bằng 'Hi'. Do đó, kết quả cuối cùng sẽ là <p>Hi</p>.
Để phân tích kịch bản và xác định các hoạt động CRUD MongoDB có lợi nhất, chúng ta cần xem xét các yêu cầu của ứng dụng quản lý nhiệm vụ. Ứng dụng cần xử lý các hoạt động tạo, đọc, cập nhật và xóa nhiệm vụ bởi người dùng. Người dùng có thể cập nhật trạng thái của một nhiệm vụ và xóa nhiệm vụ không còn cần thiết. Trong trường hợp này, chúng ta có thể sử dụng các hoạt động CRUD sau: - Tạo mới nhiệm vụ: Sử dụng insertOne để tạo mới nhiệm vụ mới. - Đọc nhiệm vụ: Sử dụng find để đọc nhiệm vụ. - Xóa nhiệm vụ: Sử dụng deleteOne để xóa nhiệm vụ không còn cần thiết. Do đó, các hoạt động CRUD MongoDB có lợi nhất cho ứng dụng quản lý nhiệm vụ là: - Sử dụng insertOne để tạo mới nhiệm vụ. - Sử dụng find để đọc nhiệm vụ. - Sử dụng deleteOne để xóa nhiệm vụ.
Để giới hạn số lượng file được tải lên tối đa 5 file, bạn có thể sử dụng Multer với phương thức upload.array(). Phương thức này cho phép bạn tải lên nhiều file cùng một lúc và giới hạn số lượng file được tải lên.
HTTPS là viết tắt của HyperText Transfer Protocol Secure, là một giao thức truyền tải siêu văn bản an toàn. Nó là một phiên bản được mã hóa của giao thức HTTP (HyperText Transfer Protocol), được sử dụng để truyền tải dữ liệu giữa máy chủ và trình duyệt web. HTTPS sử dụng chứng chỉ SSL/TLS để mã hóa dữ liệu, đảm bảo rằng dữ liệu được truyền tải an toàn và không bị truy cập trái phép. Điều này giúp bảo vệ thông tin cá nhân và bảo mật cho các giao dịch trực tuyến. Ngoài ra, HTTPS cũng giúp cải thiện uy tín và tin cậy của trang web, vì nó cho biết rằng trang web đó đã được chứng nhận và được bảo vệ bởi một tổ chức uy tín.
Một startup muốn nhanh chóng phát hành một ứng dụng di động mà không phải xây dựng một backend tùy chỉnh. Trong trường hợp này, giải pháp phù hợp nhất là sử dụng Firebase như một nền tảng BaaS. Firebase cung cấp các dịch vụ như lưu trữ dữ liệu, tính toán, và phân tích dữ liệu mà không cần phải xây dựng backend từ đầu. Điều này cho phép startup tập trung vào phát triển ứng dụng di động mà không phải lo lắng về việc xây dựng và quản lý backend. Ngoài ra, Firebase cũng cung cấp các tính năng như đăng nhập, đăng ký, và bảo mật mà không cần phải viết mã từ đầu.
Sử dụng Mongoose ODM thay vì driver MongoDB Node.js gốc mang lại một lợi ích chính là cung cấp xác thực schema và middleware cho mô hình dữ liệu. Điều này giúp đảm bảo dữ liệu được nhập vào cơ sở dữ liệu có cấu trúc và hợp lệ, giảm thiểu khả năng xảy ra lỗi do dữ liệu không đúng định dạng. Mongoose cũng cung cấp các tính năng như tạo index, thực hiện các thao tác CRUD (Create, Read, Update, Delete) dữ liệu một cách dễ dàng và hiệu quả. Ngoài ra, Mongoose hỗ trợ các tính năng như middleware, hooks và các tính năng khác giúp phát triển ứng dụng trở nên linh hoạt và mạnh mẽ hơn.
Để tránh vượt quá giới hạn 16 MB của MongoDB, bạn cần tối ưu hóa mô hình dữ liệu của mình. Một trong những cách hiệu quả là tạo ra các tài liệu riêng biệt cho dữ liệu liên quan. Điều này giúp giảm thiểu kích thước của mỗi tài liệu và tránh tình trạng vượt quá giới hạn. Ngoài ra, bạn cũng có thể áp dụng nguyên tắc phân chia dữ liệu (Normalization) để tổ chức dữ liệu một cách hợp lý và hiệu quả. Cuối cùng, việc sử dụng các loại dữ liệu một cách hiệu quả cũng là một yếu tố quan trọng trong việc tối ưu hóa mô hình dữ liệu của bạn.
Khi đánh giá giữa BaaS (Backend as a Service) và backend tự chủ, yếu tố nào thuận lợi cho một đội ngũ nhỏ? BaaS cung cấp nhiều lợi ích cho các đội ngũ nhỏ, đặc biệt là khi họ thiếu kinh nghiệm về DevOps. Bằng cách sử dụng BaaS, đội ngũ nhỏ có thể tập trung vào việc phát triển ứng dụng mà không cần lo lắng về việc quản lý và duy trì backend. Điều này giúp họ tiết kiệm thời gian và nguồn lực, đồng thời tăng cường hiệu suất và độ tin cậy của ứng dụng. Ngoài ra, BaaS thường cung cấp các tính năng và dịch vụ được tích hợp sẵn, giúp đội ngũ nhỏ có thể nhanh chóng triển khai và phân phối ứng dụng.
Khi một lỗi được ném trong một xử lý tuyến đường Express, ứng dụng Express sẽ tự động trả về trạng thái lỗi 500 với thông tin lỗi chi tiết. Điều này xảy ra vì Express sử dụng cơ chế middleware để xử lý các lỗi. Nếu một lỗi được ném trong một xử lý tuyến đường, Express sẽ tự động tìm kiếm middleware lỗi tiếp theo để xử lý. Nếu không có middleware lỗi nào được định nghĩa, Express sẽ tự động trả về trạng thái lỗi 500. Điều này giúp đảm bảo rằng ứng dụng luôn có thể trả về thông tin lỗi cho người dùng, ngay cả khi có lỗi xảy ra trong ứng dụng.
Khi một yêu cầu GET được thực hiện đến địa chỉ `http://localhost:8080/?name=Alice` trong mã Node.js sau đây, chương trình sẽ phân tích URL yêu cầu và thực hiện các hành động tương ứng. Mã Node.js sử dụng thư viện `http` để tạo một server và thư viện `url` để phân tích URL yêu cầu. Khi một yêu cầu GET được gửi đến server, chương trình sẽ phân tích URL yêu cầu và kiểm tra nếu đường dẫn yêu cầu (`pathname`) là `/`. Nếu đúng, chương trình sẽ lấy giá trị của tham số `name` từ URL yêu cầu và sử dụng nó để tạo một thông điệp chào đón. Nếu giá trị của `name` là `undefined` (do không có tham số `name` trong URL yêu cầu), chương trình sẽ sử dụng giá trị mặc định là `Guest`. Cuối cùng, chương trình sẽ trả về thông điệp chào đón với mã trạng thái 200 (OK). Trong trường hợp này, giá trị của tham số `name` là `Alice`, vì vậy thông điệp chào đón sẽ là `Hello, Alice!`.
Để ngăn chặn các cuộc tấn công brute-force khi đăng nhập, bạn có thể sử dụng middleware Express.js là express-rate-limit. Middleware này cho phép bạn giới hạn số lượng yêu cầu từ một địa chỉ IP trong một khoảng thời gian nhất định. Điều này giúp ngăn chặn các cuộc tấn công brute-force bằng cách giới hạn số lần thử đăng nhập từ một địa chỉ IP trong một khoảng thời gian nhất định. Ví dụ, bạn có thể cấu hình express-rate-limit để giới hạn 5 yêu cầu đăng nhập từ một địa chỉ IP trong 1 phút. Nếu địa chỉ IP đó vượt quá giới hạn này, nó sẽ bị chặn trong một khoảng thời gian nhất định. Điều này giúp bảo vệ hệ thống khỏi các cuộc tấn công brute-force và đảm bảo an toàn cho người dùng.