Bài trước: Web back-end (12) - Ứng dụng client-server
Ở các phần trước, chúng ta đã có trải nghiệm với lập trình client-server. Tuy nhiên, chúng ta mới chỉ dừng lại mức độ làm theo hướng dẫn, mà chưa hiểu được cơ chế giao tiếp, cách thức xử lý giữa client và server.
Phần này, chúng ta sẽ tìm hiểu chi tiết hơn về lập trình giao tiếp giữa client và server.
Như đã đề cập, các bước xử lý ở web server gồm 7 bước, như hình sau:
Cụ
thể, 7 bước xử lý gồm:
[1] nhận request
[2] phân tích request, gửi tới ứng dụng web để xử lý
[3] đọc dữ liệu từ cơ sở dữ liệu
[4] đổ dữ liệu vào trang HTML (các template HTML)
[5] gửi trang HTML (đã bao gồm dữ liệu) (response) về trình duyệt người dùng
[6] trình duyệt người dùng hiển thị nội dung response
[7] trình duyệt gửi riêng một request khác để lấy các nội dung tĩnh của ứng dụng web (HTML, CSS, JavaScript, hình ảnh, và các tài nguyên khác)
Để đơn giản, chúng ta sẽ lập trình theo tình huống sau:
- Bước 1: web server luôn ở trạng thái đang hoạt động, sẵn sàng chờ client gửi yêu cầu (request) tới.
- Bước 2: một người dùng bất kỳ, sử dụng trình duyệt web, gửi request tới web server.
- Bước 3: web server nhận request
- Bước 4: web server phân tích, xử lý request
- Bước 5: web server gửi response về client
- Bước 6: client (trình duyệt) nhận response, hiển thị thông tin lên trình duyệt.
Chúng ta cùng lập trình từng bước.
Bước 1: web server luôn ở trạng thái đang hoạt động, sẵn sàng chờ client gửi yêu cầu (request) tới
Mở tập tin index.js nhập đoạn mã sau:
[index.js]
'use strict'
const express = require('express')
const app = express();
const port = process.env.PORT || 9000
// khoi dong web server
app.listen(port, () => {
console.log(`server dang chay tren cong ${port}`);
});
Dòng mã app.listen() luôn được đặt ở cuối tập tin index.js. Dòng mã này sẽ khởi chạy web server, mở cổng có số hiệu là port (ví dụ 9000) để chờ đón các request từ client; đồng thời xuất một dòng thông báo server dang chay tren cong ${port}. Hiểu nôm na, hàm app.listen() giống như hành động mở cửa của tiệm bán quần áo, mời bà con vào mua. Tiệm quần áo là một kiot trong chợ, có số hiệu là 9000. Trong chợ có rất nhiều kiot bán quần áo, với các số hiệu khác nhau.
Mở cửa sổ dòng lệnh, chạy lệnh node index.js hoặc nodemon để thực thi mã nguồn index.js.
Lưu ý dòng thông
báo server dang chay tren cong ${port} sẽ xuất ở cửa sổ console tại máy web server, chứ không phải cửa sổ console của máy client. Bạn không tắt cửa sổ console này, vì tắt nó là web server sẽ ngừng hoạt động.
Bước 2: một người dùng bất kỳ, sử dụng trình duyệt web, gửi request tới web server
Khi web server đang chạy, và sẵn sàng nhận request. Chúng ta sẽ sử dụng trình duyệt để gửi các request về web server.
Để gửi request về web server, bạn có thể sử dụng thanh địa chỉ của trình duyệt, web form, hoặc dùng hàm JavaScript (AJAX, fetch). Để đơn giản, chúng ta sẽ sử dụng thanh địa chỉ của trình duyệt.
Mở trình duyệt web (tuy nhiên, bạn phải hiểu là mở trình duyệt trên máy tính của người dùng, vì đang trong giai đoạn phát triển phần mềm, nên máy web server và máy người dùng sẽ chạy chung trên một máy), gõ vào thanh địa chỉ URL sau:
http://localhost:9000/?name=shoes&size=40
Bấm Enter, bạn sẽ nhận được thông báo trên trình duyệt là:
Cannot GET /
Lý do có thông báo trên: client gửi request về web server, tuy nhiên, server mới chỉ mở cổng (9000) để lắng nghe request, nhận request, nhưng chưa có xử lý request và gửi trả lời (response) cho client. Nó giống như kiot đã mở bán, nhưng bên trong chưa có sản phẩm, chưa có người bán (kiot trống).
URL (Uniform Resource Locator) là địa chỉ duy nhất, dùng để định vị tài nguyên trên web, như trang HTML, API, hoặc tập tin tài nguyên tĩnh (ví dụ hình ảnh, âm thanh). Bạn có thể xem URL giống như địa chỉ của kiot.
Ví dụ một số URL:
- Định vị một trang web: https://www.example.com/index.html
- Gọi một API: https://api.example.com/v1/users/123
- Trỏ tới một hình ảnh: https://www.example.com/images/logo.png
- Định vị một ứng dụng web (trên máy cục bộ): http://localhost:9000/
Cú pháp của một URL:
protocol://domain:port/path?query#fragment
Giải thích các thành phần của một URL:
- protocol (giao thức): xác định phương thức giao tiếp mà trình duyệt sử dụng để giao tiếp với server. Các giao thức phổ biến bao gồm http (Hypertext Transfer Protocol) và https (Hypertext Transfer Protocol Secure).
- domain (tên miền): tên của máy server. Ví dụ: google.com, wikipedia.org, localhost.
- port (cổng) (tùy chọn): số cổng mà server sử dụng để lắng nghe yêu cầu (request). Cổng mặc định cho http là 80 và cho https là 443.
- path (đường dẫn): đường dẫn đến một vị trí (thư mục, tập tin, API) trên server. Ví dụ: /images/logo.png, /articles/how-to-use-url, /users.
- query (truy vấn) (tùy chọn): chuỗi các tham số được sử dụng để truyền dữ liệu đến server. Ví dụ: ?name=shoes&size=40.
- fragment (phân mảnh) (tùy chọn): một phần cụ thể của tài nguyên, thường là một phần của trang HTML. Ví dụ: #section-2.
Như vậy, URL http://localhost:9000/?name=shoes&size=40
Có nghĩa là:
- Client sử dụng giao thức http để gửi request tới web server
- Web server có địa chỉ là localhost
- Gửi request vào cổng 9000 của web server
- Gửi request, có kèm theo 2 tham số là name=shoes và size=40
Ngoài việc dùng thanh địa chỉ của trình duyệt để gửi request, chúng ta còn có 2 cách khác để gửi request là web form và hàm JavaScript (AJAX, fetch). Chúng ta sẽ tìm hiểu về web form, AJAX, fetch ở các phần sau.
13.2 Gửi response về client
Bước 3: web server nhận request, Bước [4] phân tích, xử lý request, Bước [5] gửi kết quả (response) về cho client
Tại web server, chúng ta sử dụng phương thức GET của Express để nhận và xử lý các HTTP request kiểu GET (request gửi bằng giao thức HTTP) do client gửi tới.
Cú pháp:
app.get(path, callback)
Trong đó:
- path: luồng dùng để xử lý các request kiểu GET (GET request).
- callback: hàm sẽ được thực thi khi có GET request đến luồng tương ứng. Hàm này thường có dạng (req, res) => { ... }, trong đó:
+ req (request): đối tượng chứa thông tin request từ client.
+ res (response): đối tượng dùng để gửi response về client.
Client có thể gửi nhiều loại request về web server, ví dụ: GET, POST, PUT, DELETE. Chúng ta dùng thanh địa chỉ của trình duyệt để gửi request, mặc định đó là request kiểu GET.
Dấu “/” trong http://localhost:9000/?name=shoes&size=40, có nghĩa là thư mục gốc.
Chúng ta sẽ viết đoạn mã xử lý như sau:
[index.js]
'use strict'
const express = require('express')
const app = express();
const port = process.env.PORT || 9000
//xử lý khi người dùng gửi
//request kiểu GET tới thư mục gốc (/)
app.get("/", (req,res) =>
{
//dùng phương thức query của req để lấy thông tin
//của GET request
const product = req.query.name;
const size = req.query.size;
//dùng hàm send() của đối tượng res
//để gửi dữ liệu về client
res.send(`Bạn muốn mua ${product} cỡ ${size}`);
});
//khoi dong web server
app.listen(port,() => {
console.log(`server dang chay tren cong ${port}`);
});
Lưu lại mã nguồn, khởi động lại web server (nếu dùng Nodemon thì không cần).
Bước 6: client (trình duyệt) nhận response, hiển thị thông tin lên trình duyệt
Mở trình duyệt, nhập đường vào đường dẫn URL: http://localhost:9000/?name=shoes&size=40
Trên trình duyệt sẽ xuất hiện dòng chữ.
Bạn muốn mua shoes cỡ 40
Bạn có để ý là: đoạn mã app.listen() luôn được chạy trước, mặc dù nó nằm phía dưới đoạn mã app.get(). Về mặt xử lý: có thể hiểu nôm na app.listen() là động tác mở cửa kiot, chào đón khách tới mua hàng. Trong khi các đoạn mã phía trên là việc trưng bày hàng hóa, bán hàng, thanh toán. Như vậy, chúng ta sẽ trưng bày hàng hóa, sau đó, mở cửa hàng (app.listen()). Chờ có khách tới mua (request) thì sẽ thực hiện việc bán hàng, thanh toán.
Chúng ta sẽ tìm hiểu về kiến trúc của Nodejs, Express, lập trình hướng sự kiện ở các phần sau để hiểu rõ hơn về cách xử lý mã nguồn của ứng dụng web trên nền Express và Nodejs.
13.3 Bài tập
Bài tập 13.1 Viết đoạn mã thực hiện yêu cầu sau:
Từ trình duyệt, người dùng gửi GET request, có kèm theo MSSV, HoTen, DiemTrungBinh của một sinh viên. Ví dụ:
MSSV:11223344
HoTen:Nguyễn Văn Tèo
DiemTrungBinh:7.0
Web server nhận request trên, lấy thông tin từ request và gửi về client dòng thông báo có nội dung và định dạng như sau:
Chào bạn Nguyễn Văn Teo
MSSV: 11223344
Điểm trung bình của bạn là: 70
Chúc bạn học chăm!
Câu hỏi 13.2 URL (Uniform Resource Locator) là gì? Phát biểu nào sau đây không
đúng?
A. URL là một địa chỉ duy nhất xác định vị trí của một tài nguyên trên Internet.
B. URL bao gồm các thành phần như giao thức, tên miền, đường dẫn, truy vấn và phân mảnh.
C. Phần "truy vấn" (query) trong URL được sử dụng để truyền dữ liệu đến máy chủ thông qua các tham số.
D. Giao thức "FTP" là giao thức phổ biến nhất được sử dụng trong URL để truy cập các trang web.
-----