# Xây dựng ứng dụng ngân hàng Phần 2: Tạo biểu mẫu đăng nhập và đăng ký
## Câu hỏi trước bài học
[Câu hỏi trước bài học](https://ff-quizzes.netlify.app/web/quiz/43)
Bạn đã từng điền vào một biểu mẫu trực tuyến và bị từ chối vì định dạng email không đúng? Hoặc mất toàn bộ thông tin khi nhấn nút gửi? Chúng ta đều đã gặp phải những trải nghiệm khó chịu này.
Biểu mẫu là cầu nối giữa người dùng và chức năng của ứng dụng. Giống như các quy trình cẩn thận mà kiểm soát không lưu sử dụng để hướng dẫn máy bay đến đích an toàn, biểu mẫu được thiết kế tốt cung cấp phản hồi rõ ràng và ngăn chặn các lỗi tốn kém. Ngược lại, biểu mẫu kém có thể khiến người dùng rời đi nhanh hơn một sự cố giao tiếp tại sân bay đông đúc.
Trong bài học này, chúng ta sẽ biến ứng dụng ngân hàng tĩnh của bạn thành một ứng dụng tương tác. Bạn sẽ học cách tạo biểu mẫu để xác thực đầu vào của người dùng, giao tiếp với máy chủ và cung cấp phản hồi hữu ích. Hãy nghĩ về nó như việc xây dựng giao diện điều khiển cho phép người dùng điều hướng các tính năng của ứng dụng.
Kết thúc bài học, bạn sẽ có một hệ thống đăng nhập và đăng ký hoàn chỉnh với xác thực, giúp người dùng đạt được thành công thay vì gặp phải sự thất vọng.
## Điều kiện tiên quyết
Trước khi bắt đầu xây dựng biểu mẫu, hãy đảm bảo rằng bạn đã thiết lập mọi thứ đúng cách. Bài học này tiếp nối ngay sau bài học trước, vì vậy nếu bạn đã bỏ qua, bạn có thể muốn quay lại và làm việc với các phần cơ bản trước.
### Thiết lập cần thiết
| Thành phần | Trạng thái | Mô tả |
|------------|-----------|-------|
| [Mẫu HTML](../1-template-route/README.md) | ✅ Bắt buộc | Cấu trúc cơ bản của ứng dụng ngân hàng |
| [Node.js](https://nodejs.org) | ✅ Bắt buộc | Môi trường chạy JavaScript cho máy chủ |
| [Máy chủ API ngân hàng](../api/README.md) | ✅ Bắt buộc | Dịch vụ backend để lưu trữ dữ liệu |
> 💡 **Mẹo phát triển**: Bạn sẽ chạy hai máy chủ riêng biệt đồng thời – một cho ứng dụng ngân hàng frontend và một cho API backend. Cách thiết lập này phản ánh thực tế phát triển nơi các dịch vụ frontend và backend hoạt động độc lập.
### Cấu hình máy chủ
**Môi trường phát triển của bạn sẽ bao gồm:**
- **Máy chủ frontend**: Cung cấp ứng dụng ngân hàng của bạn (thường là cổng `3000`)
- **Máy chủ API backend**: Xử lý lưu trữ và truy xuất dữ liệu (cổng `5000`)
- **Cả hai máy chủ** có thể chạy đồng thời mà không gây xung đột
**Kiểm tra kết nối API của bạn:**
```bash
curl http://localhost:5000/api
# Expected response: "Bank API v1.0.0"
```
**Nếu bạn thấy phản hồi phiên bản API, bạn đã sẵn sàng tiếp tục!**
---
## Hiểu về biểu mẫu HTML và các điều khiển
Biểu mẫu HTML là cách người dùng giao tiếp với ứng dụng web của bạn. Hãy nghĩ về chúng như hệ thống điện báo kết nối các nơi xa xôi vào thế kỷ 19 – chúng là giao thức giao tiếp giữa ý định của người dùng và phản hồi của ứng dụng. Khi được thiết kế cẩn thận, chúng bắt lỗi, hướng dẫn định dạng đầu vào và cung cấp gợi ý hữu ích.
Biểu mẫu hiện đại phức tạp hơn nhiều so với các đầu vào văn bản cơ bản. HTML5 đã giới thiệu các loại đầu vào chuyên biệt xử lý xác thực email, định dạng số và chọn ngày tự động. Những cải tiến này mang lại lợi ích cho cả khả năng truy cập và trải nghiệm người dùng di động.
### Các yếu tố cơ bản của biểu mẫu
**Các khối xây dựng mà mọi biểu mẫu cần có:**
```html
```
**Mã này làm gì:**
- **Tạo** một container biểu mẫu với một định danh duy nhất
- **Xác định** phương thức HTTP để gửi dữ liệu
- **Liên kết** nhãn với đầu vào để tăng khả năng truy cập
- **Định nghĩa** nút gửi để xử lý biểu mẫu
### Các loại đầu vào và thuộc tính hiện đại
| Loại đầu vào | Mục đích | Ví dụ sử dụng |
|--------------|----------|---------------|
| `text` | Đầu vào văn bản chung | `` |
| `email` | Xác thực email | `` |
| `password` | Nhập văn bản ẩn | `` |
| `number` | Đầu vào số | `` |
| `tel` | Số điện thoại | `` |
> 💡 **Lợi ích của HTML5 hiện đại**: Sử dụng các loại đầu vào cụ thể cung cấp xác thực tự động, bàn phím di động phù hợp và hỗ trợ khả năng truy cập tốt hơn mà không cần thêm JavaScript!
### Các loại nút và hành vi
```html
```
**Mỗi loại nút làm gì:**
- **Nút gửi**: Kích hoạt gửi biểu mẫu và gửi dữ liệu đến điểm cuối được chỉ định
- **Nút đặt lại**: Khôi phục tất cả các trường biểu mẫu về trạng thái ban đầu
- **Nút thông thường**: Không cung cấp hành vi mặc định, yêu cầu JavaScript tùy chỉnh để hoạt động
> ⚠️ **Lưu ý quan trọng**: Phần tử `` tự đóng và không yêu cầu thẻ đóng. Thực hành tốt nhất hiện đại là viết `` mà không có dấu gạch chéo.
### Tạo biểu mẫu đăng nhập của bạn
Bây giờ hãy tạo một biểu mẫu đăng nhập thực tế minh họa các thực hành biểu mẫu HTML hiện đại. Chúng ta sẽ bắt đầu với cấu trúc cơ bản và dần dần cải thiện nó với các tính năng truy cập và xác thực.
```html
Bank App
Login
```
**Phân tích những gì xảy ra ở đây:**
- **Cấu trúc** biểu mẫu với các phần tử HTML5 ngữ nghĩa
- **Nhóm** các phần tử liên quan bằng các container `div` với các lớp có ý nghĩa
- **Liên kết** nhãn với đầu vào bằng các thuộc tính `for` và `id`
- **Bao gồm** các thuộc tính hiện đại như `autocomplete` và `placeholder` để cải thiện UX
- **Thêm** `novalidate` để xử lý xác thực bằng JavaScript thay vì mặc định của trình duyệt
### Sức mạnh của nhãn đúng cách
**Tại sao nhãn quan trọng đối với phát triển web hiện đại:**
```mermaid
graph TD
A[Label Element] --> B[Screen Reader Support]
A --> C[Click Target Expansion]
A --> D[Form Validation]
A --> E[SEO Benefits]
B --> F[Accessible to all users]
C --> G[Better mobile experience]
D --> H[Clear error messaging]
E --> I[Better search ranking]
```
**Những gì nhãn đúng cách đạt được:**
- **Cho phép** trình đọc màn hình thông báo rõ ràng các trường biểu mẫu
- **Mở rộng** khu vực có thể nhấp (nhấp vào nhãn sẽ tập trung vào đầu vào)
- **Cải thiện** khả năng sử dụng di động với các mục tiêu chạm lớn hơn
- **Hỗ trợ** xác thực biểu mẫu với các thông báo lỗi có ý nghĩa
- **Tăng cường** SEO bằng cách cung cấp ý nghĩa ngữ nghĩa cho các phần tử biểu mẫu
> 🎯 **Mục tiêu truy cập**: Mỗi đầu vào biểu mẫu nên có một nhãn liên kết. Thực hành đơn giản này giúp biểu mẫu của bạn dễ sử dụng hơn cho mọi người, bao gồm cả người dùng khuyết tật, và cải thiện trải nghiệm cho tất cả người dùng.
### Tạo biểu mẫu đăng ký
Biểu mẫu đăng ký yêu cầu thông tin chi tiết hơn để tạo tài khoản người dùng hoàn chỉnh. Hãy xây dựng nó với các tính năng HTML5 hiện đại và khả năng truy cập nâng cao.
```html
Register
```
**Trong đoạn mã trên, chúng ta đã:**
- **Sắp xếp** từng trường trong các container div để cải thiện kiểu dáng và bố cục
- **Thêm** các thuộc tính `autocomplete` phù hợp để hỗ trợ tự động điền của trình duyệt
- **Bao gồm** văn bản gợi ý hữu ích để hướng dẫn đầu vào của người dùng
- **Đặt** các giá trị mặc định hợp lý bằng thuộc tính `value`
- **Áp dụng** các thuộc tính xác thực như `required`, `maxlength`, và `min`
- **Sử dụng** `type="number"` cho trường số dư với hỗ trợ số thập phân
### Khám phá các loại đầu vào và hành vi
**Các loại đầu vào hiện đại cung cấp chức năng nâng cao:**
| Tính năng | Lợi ích | Ví dụ |
|-----------|---------|-------|
| `type="number"` | Bàn phím số trên di động | Nhập số dư dễ dàng hơn |
| `step="0.01"` | Kiểm soát độ chính xác số thập phân | Cho phép nhập số lẻ trong tiền tệ |
| `autocomplete` | Tự động điền của trình duyệt | Hoàn thành biểu mẫu nhanh hơn |
| `placeholder` | Gợi ý ngữ cảnh | Hướng dẫn kỳ vọng của người dùng |
> 🎯 **Thử thách truy cập**: Hãy thử điều hướng các biểu mẫu chỉ bằng bàn phím của bạn! Sử dụng `Tab` để di chuyển giữa các trường, `Space` để chọn hộp kiểm, và `Enter` để gửi. Trải nghiệm này giúp bạn hiểu cách người dùng trình đọc màn hình tương tác với biểu mẫu của bạn.
## Hiểu về các phương thức gửi biểu mẫu
Khi ai đó điền vào biểu mẫu của bạn và nhấn gửi, dữ liệu đó cần được gửi đến đâu đó – thường là đến một máy chủ có thể lưu trữ nó. Có một số cách khác nhau để thực hiện điều này, và biết cách sử dụng cách nào có thể giúp bạn tránh được một số rắc rối sau này.
Hãy cùng xem điều gì thực sự xảy ra khi ai đó nhấn nút gửi.
### Hành vi mặc định của biểu mẫu
Đầu tiên, hãy quan sát điều gì xảy ra với việc gửi biểu mẫu cơ bản:
**Kiểm tra các biểu mẫu hiện tại của bạn:**
1. Nhấn nút *Đăng ký* trong biểu mẫu của bạn
2. Quan sát các thay đổi trong thanh địa chỉ của trình duyệt
3. Lưu ý cách trang tải lại và dữ liệu xuất hiện trong URL

### So sánh các phương thức HTTP
```mermaid
graph TD
A[Form Submission] --> B{HTTP Method}
B -->|GET| C[Data in URL]
B -->|POST| D[Data in Request Body]
C --> E[Visible in address bar]
C --> F[Limited data size]
C --> G[Bookmarkable]
D --> H[Hidden from URL]
D --> I[Large data capacity]
D --> J[More secure]
```
**Hiểu sự khác biệt:**
| Phương thức | Trường hợp sử dụng | Vị trí dữ liệu | Mức độ bảo mật | Giới hạn kích thước |
|-------------|-------------------|---------------|----------------|---------------------|
| `GET` | Truy vấn tìm kiếm, bộ lọc | Tham số URL | Thấp (hiển thị) | ~2000 ký tự |
| `POST` | Tài khoản người dùng, dữ liệu nhạy cảm | Nội dung yêu cầu | Cao (ẩn) | Không giới hạn thực tế |
**Hiểu sự khác biệt cơ bản:**
- **GET**: Thêm dữ liệu biểu mẫu vào URL dưới dạng tham số truy vấn (phù hợp cho các thao tác tìm kiếm)
- **POST**: Bao gồm dữ liệu trong nội dung yêu cầu (cần thiết cho thông tin nhạy cảm)
- **Giới hạn của GET**: Giới hạn kích thước, dữ liệu hiển thị, lịch sử trình duyệt tồn tại
- **Ưu điểm của POST**: Dung lượng dữ liệu lớn, bảo vệ quyền riêng tư, hỗ trợ tải lên tệp
> 💡 **Thực hành tốt nhất**: Sử dụng `GET` cho biểu mẫu tìm kiếm và bộ lọc (truy xuất dữ liệu), sử dụng `POST` cho đăng ký người dùng, đăng nhập và tạo dữ liệu.
### Cấu hình gửi biểu mẫu
Hãy cấu hình biểu mẫu đăng ký của bạn để giao tiếp đúng cách với API backend bằng phương thức POST:
```html
```
**Hiểu xác thực nâng cao:**
- **Kết hợp** chỉ báo trường bắt buộc với mô tả hữu ích
- **Bao gồm** thuộc tính `pattern` để xác thực định dạng
- **Cung cấp** thuộc tính `title` để hỗ trợ truy cập và hiển thị tooltip
- **Thêm** văn bản trợ giúp để hướng dẫn nhập liệu
- **Sử dụng** cấu trúc HTML ngữ nghĩa để cải thiện khả năng truy cập
### Quy tắc xác thực nâng cao
**Những gì mỗi quy tắc xác thực đạt được:**
| Trường | Quy tắc xác thực | Lợi ích cho người dùng |
|--------|------------------|------------------------|
| Tên người dùng | `required`, `minlength="3"`, `maxlength="20"`, `pattern="[a-zA-Z0-9_]+"` | Đảm bảo định danh hợp lệ, duy nhất |
| Tiền tệ | `required`, `maxlength="3"`, `pattern="[A-Z$€£¥₹]+"` | Chấp nhận các ký hiệu tiền tệ phổ biến |
| Số dư | `min="0"`, `step="0.01"`, `type="number"` | Ngăn số dư âm |
| Mô tả | `maxlength="100"` | Giới hạn độ dài hợp lý |
### Kiểm tra hành vi xác thực
**Thử các kịch bản xác thực sau:**
1. **Gửi** biểu mẫu với các trường bắt buộc để trống
2. **Nhập** tên người dùng ngắn hơn 3 ký tự
3. **Thử** ký tự đặc biệt trong trường tên người dùng
4. **Nhập** số dư âm

**Những gì bạn sẽ quan sát:**
- **Trình duyệt hiển thị** thông báo xác thực gốc
- **Thay đổi kiểu dáng** dựa trên trạng thái `:valid` và `:invalid`
- **Gửi biểu mẫu** bị ngăn cho đến khi tất cả xác thực đều đạt
- **Tự động tập trung** vào trường đầu tiên không hợp lệ
### Xác thực phía khách hàng và phía máy chủ
```mermaid
graph LR
A[Client-Side Validation] --> B[Instant Feedback]
A --> C[Better UX]
A --> D[Reduced Server Load]
E[Server-Side Validation] --> F[Security]
E --> G[Data Integrity]
E --> H[Business Rules]
A -.-> I[Both Required]
E -.-> I
```
**Tại sao bạn cần cả hai lớp:**
- **Xác thực phía khách hàng**: Cung cấp phản hồi ngay lập tức và cải thiện trải nghiệm người dùng
- **Xác thực phía máy chủ**: Đảm bảo an toàn và xử lý các quy tắc kinh doanh phức tạp
- **Cách tiếp cận kết hợp**: Tạo ứng dụng thân thiện với người dùng và an toàn
- **Cải tiến tiến bộ**: Hoạt động ngay cả khi JavaScript bị vô hiệu hóa
> 🛡️ **Nhắc nhở về bảo mật**: Không bao giờ chỉ tin tưởng vào xác thực phía khách hàng! Người dùng độc hại có thể vượt qua các kiểm tra phía khách hàng, vì vậy xác thực phía máy chủ là điều cần thiết để đảm bảo an toàn và tính toàn vẹn dữ liệu.
---
---
## Thử thách GitHub Copilot Agent 🚀
Sử dụng chế độ Agent để hoàn thành thử thách sau:
**Mô tả:** Nâng cấp biểu mẫu đăng ký với xác thực phía khách hàng toàn diện và phản hồi người dùng. Thử thách này sẽ giúp bạn thực hành xác thực biểu mẫu, xử lý lỗi và cải thiện trải nghiệm người dùng với phản hồi tương tác.
**Yêu cầu:** Tạo hệ thống xác thực biểu mẫu hoàn chỉnh cho biểu mẫu đăng ký bao gồm: 1) Phản hồi xác thực theo thời gian thực cho từng trường khi người dùng nhập, 2) Thông báo xác thực tùy chỉnh xuất hiện bên dưới mỗi trường nhập, 3) Trường xác nhận mật khẩu với xác thực khớp, 4) Chỉ báo trực quan (như dấu kiểm màu xanh cho các trường hợp hợp lệ và cảnh báo màu đỏ cho các trường hợp không hợp lệ), 5) Nút gửi chỉ được kích hoạt khi tất cả các xác thực đều đạt. Sử dụng các thuộc tính xác thực HTML5, CSS để tạo kiểu cho trạng thái xác thực và JavaScript để tạo hành vi tương tác.
Tìm hiểu thêm về [chế độ agent](https://code.visualstudio.com/blogs/2025/02/24/introducing-copilot-agent-mode) tại đây.
## 🚀 Thử thách
Hiển thị thông báo lỗi trong HTML nếu người dùng đã tồn tại.
Dưới đây là một ví dụ về giao diện trang đăng nhập cuối cùng sau khi thêm một chút kiểu dáng:

## Câu hỏi sau bài giảng
[Câu hỏi sau bài giảng](https://ff-quizzes.netlify.app/web/quiz/44)
## Ôn tập & Tự học
Các nhà phát triển đã rất sáng tạo trong nỗ lực xây dựng biểu mẫu của họ, đặc biệt là về chiến lược xác thực. Tìm hiểu về các luồng biểu mẫu khác nhau bằng cách xem qua [CodePen](https://codepen.com); bạn có thể tìm thấy một số biểu mẫu thú vị và truyền cảm hứng không?
## Bài tập
[Thiết kế ứng dụng ngân hàng của bạn](assignment.md)
---
**Tuyên bố miễn trừ trách nhiệm**:
Tài liệu này đã được dịch bằng dịch vụ dịch thuật AI [Co-op Translator](https://github.com/Azure/co-op-translator). Mặc dù chúng tôi cố gắng đảm bảo độ chính xác, xin lưu ý rằng các bản dịch tự động có thể chứa lỗi hoặc không chính xác. Tài liệu gốc bằng ngôn ngữ bản địa nên được coi là nguồn thông tin chính thức. Đối với thông tin quan trọng, chúng tôi khuyến nghị sử dụng dịch vụ dịch thuật chuyên nghiệp từ con người. Chúng tôi không chịu trách nhiệm cho bất kỳ sự hiểu lầm hoặc diễn giải sai nào phát sinh từ việc sử dụng bản dịch này.