Hai trang web trên màn hình. Trang đầu là một trang game: sân chơi, điểm số, nút "chơi lại". Trang thứ hai là trang của một xưởng, có form "đặt hàng". Cả hai đều mở trong trình duyệt, cả hai đều dựng từ HTML, CSS và JavaScript, cả hai trông đều hoàn thiện như nhau. Trang đầu tiên đăng lên chỉ mất một phút: đưa thư mục lên hosting, có ngay liên kết. Với trang thứ hai, agent nhiều khả năng sẽ dừng lại và hỏi máy chủ đặt ở đâu, đơn hàng lưu vào chỗ nào.
Khác biệt không nằm ở độ phức tạp hay vẻ đẹp. Nó nằm ở chỗ ai phải làm việc gì khi người dùng nhấn nút, và dữ liệu sau đó phải nằm ở đâu. Hãy cùng làm rõ ba từ - trang tĩnh, frontend và backend - xem dữ liệu sống ở đâu và vì sao điều đó quyết định cách đăng trang. Cuối bài sẽ nói agent tự hỏi gì trước khi bạn kịp nói "đăng đi", và bạn nên hỏi lại nó điều gì.

1. Trang tĩnh
Trang tĩnh là trang web làm từ các file có sẵn: index.html, style.css, script, hình ảnh, font. Máy chủ chỉ lưu giữ chúng và trả về đúng những file đó cho mọi người truy cập, không tính toán gì thêm và không ghi nhớ gì về người dùng. Mọi việc - hiển thị, tính toán, phản ứng khi nhấp chuột - đều do trình duyệt của người dùng thực hiện trên máy của họ.
Hãy lấy ví dụ một portfolio chỉ có một trang. Trong thư mục có index.html chứa phần giới thiệu bản thân và danh sách tác phẩm, style.css, chục tấm ảnh và một script nhỏ. Người dùng mở liên kết, trình duyệt tải các file về và dựng thành trang. Nhấp vào một tác phẩm sẽ phóng to ảnh lên, nút chuyển chế độ tối đổi màu sắc: đó là việc của script chạy trong trình duyệt. Sau khi đã trả file xong, máy chủ không còn tham gia vào chuyện gì nữa: nó không quan tâm ai vào và ai nhấn gì. Có tác phẩm mới - bạn sửa index.html, đặt thêm ảnh vào và đăng lại thư mục; không có cách nào khác để thay đổi gì ở đây, và người thay đổi trang là bạn, không phải người xem.
Theo cùng mô hình này còn có:
- áp phích buổi hòa nhạc hay sự kiện: ngày giờ, địa điểm, chương trình, bản đồ đường đi; nút "mua vé" dẫn sang trang của người bán vé, còn bản thân áp phích không bán gì cả;
- landing page cho sản phẩm hoặc dịch vụ, nếu trên đó chỉ có số điện thoại và email thay vì form;
- tài liệu hướng dẫn dự án: hàng chục trang có menu và liên kết qua lại, nhưng vẫn chỉ là các file;
- blog không có bình luận: mỗi bài viết là một file, bài mới cũng được đăng theo cách y hệt các bài khác;
- game trong trình duyệt. Đúng vậy, game cũng thế: nước đi, điểm số và animation đều được tính trong trình duyệt, máy chủ không quan tâm đến chúng.
Từ này mô tả máy chủ, chứ không phải màn hình. Máy chủ trả về các file y nguyên, không thay đổi gì trong đó - đó chính là ý nghĩa của từ "tĩnh", kể cả khi trên màn hình mọi thứ đang chuyển động, nhấp nháy và phản ứng với từng cú nhấp chuột.
Ranh giới của trang tĩnh nằm ở đâu, sẽ thấy rõ khi chia công việc của trang web thành hai nửa: phần trình duyệt làm và phần máy chủ làm. Hai nửa này đều có tên riêng.
2. Frontend hoạt động trong trình duyệt
Frontend là tất cả những gì chạy trên máy tính của người dùng: markup, style và script mà trình duyệt đã nhận và tự chạy ở đó. "Phần trước", phần mà bạn nhìn thấy được. (Người ta hay coi nó "chỉ là giao diện", nhưng thực ra đó là toàn bộ phần người dùng tương tác, còn với trang tĩnh thì đó là toàn bộ trang web.)
Frontend làm được khá nhiều việc: hiển thị trang, tính nước đi trong game, kiểm tra trước khi gửi xem một ô của form có bị bỏ trống không, ghi nhớ thứ gì đó đến lần truy cập sau - để làm việc này trình duyệt có kho lưu trữ riêng, agent sẽ gọi nó là localStorage. Điều nó không làm được là chia sẻ. Kho lưu trữ đó chỉ tồn tại trong trình duyệt này, trên thiết bị này, không ở đâu khác. Ranh giới này gây cản trở ở đâu và không gây cản trở ở đâu, hai ví dụ sau sẽ cho thấy rõ.
Điểm cao nhất trong game. Ván chơi kết thúc, script so kết quả với kỷ lục trước đó và ghi kỷ lục mới vào kho lưu trữ của trình duyệt. Hôm sau người chơi mở lại trang trên cùng trình duyệt, cùng laptop - kỷ lục vẫn còn nguyên. Mở trên điện thoại - chỗ đó trống trơn, điện thoại có kho lưu trữ riêng của nó. Còn bạn, người làm ra game, sẽ không bao giờ thấy được kỷ lục đó. Và cũng chẳng sao cả: nó chỉ cần cho đúng người chơi ấy, và trang vẫn cứ là trang tĩnh.
Đơn đặt hàng của xưởng. Khách mô tả việc cần làm, để lại số điện thoại, nhấn "gửi". Script có thể kiểm tra các ô đã điền chưa, nhưng đến đó là hết đường: nếu ghi đơn hàng vào kho lưu trữ của trình duyệt thì đơn hàng sẽ nằm nguyên trên điện thoại của khách, còn người thợ sẽ chẳng bao giờ biết đến nó. Đơn hàng cần được người khác đọc trên thiết bị khác, nghĩa là dữ liệu phải rời khỏi máy của khách, và ở đầu bên kia phải có ai đó nhận và lưu lại. Một trang chỉ gồm toàn file thì không có "ai đó" như vậy.
Mọi thứ chỉ liên quan đến một người dùng trên một thiết bị thì frontend tự lo được. Phần còn lại là việc của nửa kia.
Bất cứ thứ gì nằm trong file của trang web, người dùng đều có thể mở ra và đọc được, script cũng vậy. Một khóa dùng cho dịch vụ bên ngoài - dự báo thời tiết, bản đồ, thanh toán - nếu đặt trong frontend, ai cũng đọc được và có thể dùng nhân danh bạn. Những khóa như vậy thực ra nên đặt ở đâu là một chuyện khác, nhưng chắc chắn không phải trong file của trang.
3. Backend hoạt động trên máy chủ
Backend là chương trình chạy trên máy chủ và trả lời các yêu cầu từ trình duyệt. Nhận đơn hàng và lưu nó lại. Kiểm tra tên đăng nhập và mật khẩu. Trả về danh sách sản phẩm. Nó vẫn hoạt động ngay cả khi người dùng đã đóng tab, và phải luôn chạy, cũng như bản thân máy chủ - một máy tính không bao giờ tắt.
Trên sơ đồ là hai con đường cùng một hình dạng: nhấp chuột, làm việc, kết quả. Chúng khác nhau ở ô chính giữa - ai làm việc và làm việc gì. Ở trên, sau một nước đi trong game, JavaScript trong trình duyệt tính điểm, lưu kỷ lục và vẽ lại sân chơi, tất cả đều diễn ra trên máy tính người dùng. Ở dưới, cú nhấp "gửi" biến thành một yêu cầu, yêu cầu đi tới máy chủ, chương trình nhận nó, lưu đơn hàng ngay trên máy chủ của mình rồi trả lời trình duyệt, và chính câu trả lời đó mới hiện lên màn hình. Đơn hàng nằm cụ thể ở đâu trên máy chủ sẽ nói ở phần sau. Câu hỏi "ai làm việc" chính là ranh giới giữa hai loại trang web.
Ba dấu hiệu dễ nhận biết cho thấy không thể thiếu backend:
- đăng nhập bằng mật khẩu: phải có ai đó lưu mật khẩu và kiểm tra chúng, và đó không thể là trình duyệt của người dùng;
- dữ liệu mà người khác cần thấy: bình luận, đơn hàng, danh sách chung;
- hành động nhân danh bạn: gửi email, thực hiện thanh toán, ghi gì đó vào một dịch vụ khác bằng khóa của bạn.
Backend có thể viết bằng ngôn ngữ bất kỳ: JavaScript (khi đó gọi là Node.js), Python, Java, và cả chục ngôn ngữ khác. Điều quan trọng với bài viết này không phải là chuyện đó, mà là chương trình phải chạy liên tục ở đâu đó, và "đâu đó" này không phải là trình duyệt. Địa chỉ trang web dẫn đến một vị trí trên máy chủ, giống như với trang tĩnh, chỉ khác là ở vị trí đó giờ không phải một file, mà là một chương trình tự dựng câu trả lời ngay tại chỗ.
4. Dữ liệu sống ở đâu
Ai phải làm việc sau cú nhấp chuột là do dữ liệu quyết định: chúng nằm ở đâu và ai cần thấy chúng. Không phải hình thức trang web hay độ phức tạp của nó. Có ba nơi.
Trong file của dự án. Nội dung trang, hình ảnh, luật chơi. Giống nhau cho mọi người dùng và chỉ thay đổi khi có lần deploy mới: sửa file, đăng lại.
Trong trình duyệt của người dùng. Cài đặt, điểm cao nhất, bản nháp form mà bạn không muốn mất khi tải lại trang. Chỉ người dùng đó trên thiết bị đó nhìn thấy. Chúng biến mất khi xóa dữ liệu trang web, không có trong cửa sổ ẩn danh, cũng không có ở trình duyệt khác hay thiết bị khác, và bạn không hề biết gì về chúng.
Trong cơ sở dữ liệu trên máy chủ. Đơn hàng, bình luận, tài khoản. Ai được phép đều thấy, kể cả bạn. Chúng tồn tại bất kể lúc đó có ai mở tab hay không. Để dữ liệu vào được đó, cần một chương trình trên máy chủ nhận dữ liệu và ghi lại.
Trên sơ đồ vẫn là hai thế giới như sơ đồ trên, chỉ khác là giờ trong đó chứa dữ liệu, chứ không phải người thực hiện công việc. File của trang web được sao đến từng người dùng, nên ai cũng thấy cùng một trang. Kho lưu trữ trình duyệt là ô duy nhất không có mũi tên: dữ liệu ở đó có thật, nhưng không rời khỏi thiết bị, và bạn sẽ không bao giờ thấy được chúng. Dữ liệu chỉ vào được cơ sở dữ liệu qua chương trình, nhưng bù lại từ đó ai được phép đều thấy.
Thay vì lý thuyết, hãy tự hỏi một câu: người khác có cần thấy thứ người này vừa nhập không? "Ghi nhớ điểm cao nhất" - không, vậy là kho lưu trữ trình duyệt, và trang vẫn là trang tĩnh. "Lưu đơn hàng" - có, vậy là cần cơ sở dữ liệu và chương trình ghi vào đó. Câu hỏi này có một ngoại lệ, và nó không liên quan đến dữ liệu: khóa dùng cho dịch vụ bên ngoài. Nếu có khóa thì câu trả lời "không" không còn cứu được bạn: khóa không được nằm trong file, nghĩa là cần một chương trình trên máy chủ gọi tới dịch vụ bên ngoài nhân danh bạn, hoặc một dịch vụ trung gian làm việc đó thay bạn.
Có trường hợp lửng lơ ở giữa. Form đặt hàng có thể do một dịch vụ bên ngoài nhận thay bạn: người dùng nhấn "gửi", dữ liệu không đi tới máy chủ của bạn mà đi tới họ, rồi từ đó gửi email cho bạn. Đây vẫn là backend, chỉ là không phải backend của bạn. Agent sẽ gọi tên nó ra nếu bạn hỏi; điều quan trọng lúc này là hiểu rằng một form không thể hoạt động nếu thiếu chương trình của ai đó trên máy chủ.
5. Vì sao cách deploy lại khác nhau
Trang tĩnh được đăng bằng cách sao chép: thư mục được đưa lên hosting (một máy chủ của người khác, trả file của bạn cho bất kỳ ai muốn xem), có ngay liên kết, muốn cập nhật thì sao chép lại lần nữa. Vậy là xong.
Với backend thì khác. Trên máy chủ phải có sẵn môi trường cho ngôn ngữ của chương trình - chính Python hay Node.js, thiếu chúng thì không có gì để chạy code. Chương trình phải luôn chạy và tự khởi động lại nếu bị sập. Bên cạnh đó phải có một cơ sở dữ liệu đang hoạt động. Khóa để vào cơ sở dữ liệu và các dịch vụ bên ngoài phải được đặt sao cho chương trình đọc được còn người dùng thì không. Mỗi phần trong số này được cập nhật riêng và hỏng theo cách riêng của nó.
Từ đó dẫn đến một loại hosting khác: loại chạy được chương trình, chứ không chỉ trả file. Ở đó người ta thường trả tiền theo thời gian chương trình chạy và theo dung lượng cho cơ sở dữ liệu. Vẫn có phương án miễn phí, nhưng đi kèm điều kiện thay đổi còn nhanh hơn cả bài viết này.
| Trang tĩnh | Trang có backend | |
|---|---|---|
| Gửi cái gì | thư mục chứa file | code của chương trình |
| Máy chủ cần có gì | không cần gì của bạn cả: bản thân hosting đã biết trả file | môi trường cho ngôn ngữ, chương trình đang chạy, cơ sở dữ liệu |
| Dữ liệu nằm ở đâu | trong file và trong trình duyệt người dùng | trong cơ sở dữ liệu trên máy chủ |
| Cái gì cần giữ bí mật | trong bản thân file của trang - không có gì | khóa vào cơ sở dữ liệu và các dịch vụ bên ngoài |
| Cập nhật thế nào | sao chép lại thư mục | cập nhật code, khởi động lại chương trình, đôi khi cập nhật cả cơ sở dữ liệu |
| Chi phí thế nào | với trang nhỏ thường miễn phí | thường trả tiền theo thời gian chạy và theo cơ sở dữ liệu |
Có một điểm cần làm rõ ở dòng về bí mật. Trang tĩnh vẫn có thể có khóa vào hosting, nếu bạn tạo nó để có liên kết cố định, nhưng khóa đó sống tách biệt với thư mục của trang và không được đặt vào trong đó.
Câu "dựng một máy chủ" trong câu trả lời của agent nghe bình thường như "tạo một file". Nhưng đằng sau câu đó là cả cột bên phải của bảng trên, và gần như dòng nào sau này bạn cũng phải duy trì.
6. Đăng trang tĩnh ở đâu
Vì trang tĩnh được đăng bằng cách sao chép, nên có rất nhiều dịch vụ hosting cho nó, và phần lớn miễn phí cho một trang nhỏ. Dưới đây là năm dịch vụ hay gặp nhất. Trong bảng sẽ có từ "repository": tạm thời hiểu nó là thư mục dự án được quản lý phiên bản là đủ, nói chi tiết hơn thì chưa cần lúc này.
| Hosting | Cần gì đầu vào | Liên kết trông ra sao | Miễn phí cho trang nhỏ |
|---|---|---|---|
| Tiiny Host | thư mục hoặc file qua trang web; agent tự đăng được lên đó | name.tiiny.site | có, giới hạn số lượng trang; liên kết tạm thời không cần tài khoản |
| GitHub Pages | repository trên GitHub, file được lấy thẳng từ đó | name.github.io hoặc name.github.io/project | có, cho repository công khai và không dùng để kinh doanh |
| Netlify | kéo thả thư mục trong trình duyệt, lệnh trong terminal hoặc repository | name.netlify.app | có |
| Vercel | kéo thả thư mục, lệnh hoặc repository | name.vercel.app | có, cho dự án cá nhân phi thương mại |
| Cloudflare Pages | thư mục hoặc file nén qua bảng điều khiển, thư mục bằng lệnh, hoặc repository | name.pages.dev | có |
Cách chọn. Để đưa ra xem và thảo luận - chọn dịch vụ nào cho liên kết ngay mà không cần đăng ký. Để dùng lâu dài - dịch vụ nào bạn đã có tài khoản. Dự án nằm trong repository - chọn dịch vụ kết nối với repository và tự cập nhật mỗi khi có thay đổi. Chọn dịch vụ nào cũng không ảnh hưởng đến hình thức trang sau khi đăng: file vẫn là file đó.
Nếu trang web có backend
Chương trình cần một dịch vụ hosting biết làm nhiều hơn là trả file, nó phải chạy được code của bạn và giữ cho code luôn chạy: đầu vào của nó không phải một thư mục, mà là một chương trình, và nó tự chuẩn bị môi trường cho chương trình đó. Một số dịch vụ trong bảng trên cũng có chế độ này, nhưng thường người ta bắt đầu với hai dịch vụ được làm riêng cho chương trình:
| Hosting | Cần gì đầu vào | Liên kết trông ra sao | Phương án miễn phí |
|---|---|---|---|
| Render | repository trên GitHub hoặc dịch vụ tương tự; repository đã kết nối tự cập nhật mỗi khi có thay đổi | name.onrender.com | có, nhưng chương trình sẽ ngủ nếu lâu không có ai truy cập, và không tỉnh dậy ngay; cơ sở dữ liệu miễn phí chỉ tồn tại trong thời gian giới hạn |
| Railway | repository hoặc lệnh trong terminal | name.up.railway.app | có gói với một khoản credit nhỏ hàng tháng, sau đó phải trả phí |
Backend miễn phí luôn có cái giá riêng của nó: ở dịch vụ này chương trình đi ngủ, và người dùng đầu tiên sau khoảng nghỉ phải chờ nó thức dậy, ở dịch vụ khác thì credit dùng hết. Khi lượng người dùng tăng lên, bạn sẽ phải trả tiền để duy trì hoạt động liên tục. Trang tĩnh không gặp vấn đề này: file thì không bao giờ ngủ.
Điều kiện và giới hạn của mọi dịch vụ đều thay đổi, còn sản phẩm thì bị đổi tên và gộp lại: ví dụ Cloudflare giờ đã khuyên bắt đầu dự án mới không phải trong Pages mà trong Workers, nơi file tĩnh cũng được đăng theo cách tương tự. Các con số cụ thể cố tình không được đưa vào hai bảng trên: trước khi chọn, hãy vào xem trang bảng giá.
7. Nên hỏi agent gì trước khi đăng trang
Agent nhìn vào thư mục và thường tự gọi tên đúng loại dự án. Toàn file, không có chương trình - nó sẽ đề nghị hosting cho trang tĩnh, kể cả khi trong đó có một form không có nơi nào để gửi dữ liệu đi: điều này nó không phải lúc nào cũng nhận ra. Có server.js hoặc app.py - nó sẽ nói cần một máy chủ, và hỏi máy chủ sẽ đặt ở đâu. Nếu nó không nói gì hoặc nói quá vội, hãy tự hỏi:
Hãy xem dự án và cho tôi biết đây là trang tĩnh hay cần một máy chủ.
Liệt kê theo từng điểm chính xác cái gì đòi hỏi máy chủ.
Với mỗi điểm, đề xuất xem có thể bỏ qua máy chủ hay hoãn lại được không.Câu trả lời phụ thuộc vào từng dự án nên ở đây không có sẵn. Nhưng có vài điều đáng để ý trong bất kỳ câu trả lời nào.
- Đừng đồng ý ngay với "cần một máy chủ". Hãy hỏi chính xác cái gì đòi hỏi điều đó và liệu có thể làm trong trình duyệt hay hoãn lại được không - ví dụ ra mắt phiên bản đầu tiên không có form. Agent rất sẵn lòng dựng backend ở những chỗ chỉ cần kho lưu trữ trình duyệt là đủ.
- Và ngược lại: nếu dữ liệu cần được dùng chung, agent nhiều khả năng sẽ nói không thể chỉ dùng trang tĩnh. Đây không phải là làm phức tạp thêm, mà chỉ là gọi đúng tên sự việc. không có gì để tranh cãi ở đây cả.
- Về khóa dùng cho dịch vụ bên ngoài, agent sẽ hỏi nên đặt nó ở đâu. Câu trả lời "vào file của trang" là sai, và một agent tốt sẽ tự nói ra điều đó. Những khóa như vậy có chỗ riêng nằm ngoài file của trang, và agent phải tự gọi tên chỗ đó ra, chứ không đề nghị ghi khóa thẳng vào trang.
- Trước khi deploy trang tĩnh, agent chỉ cần một thư mục. Trước khi deploy backend, nó còn cần câu trả lời về cơ sở dữ liệu, môi trường và các bí mật. Nếu không có câu hỏi nào mà máy chủ vẫn "được dựng lên", hãy xem lại nó đã làm chính xác những gì và ở đâu.
"Đây có phải trang tĩnh không? Cái gì trong đó đòi hỏi máy chủ? Có thể bỏ qua nó được không?" Ba câu hỏi trong một dòng, và agent sẽ phân loại rõ dự án trước khi kịp dựng bất cứ thứ gì.
Từ "tĩnh" và "backend" không mô tả độ phức tạp, mà mô tả vị trí: việc diễn ra ở đâu và dữ liệu sống ở đâu. Khi biết được vị trí đó, cách đăng trang sẽ tự nó hiện ra.
Điều kiện của các dịch vụ hosting thay đổi theo thời gian, hãy kiểm tra trên trang bảng giá của họ.
GO TO FULL VERSION