Ứng dụng trang đơn là những ứng dụng nằm trên một tài liệu HTML. Điều này có nghĩa là nếu bạn muốn hiển thị một số nội dung khác nhau cho người dùng, tùy thuộc vào trạng thái của ứng dụng, bạn sẽ cần thực hiện một số thao tác DOM (cắt và thay thế các phần tử nhất định của tài liệu hiện tại bằng HTML khác) để cập nhật 'chế độ xem' mà người dùng nhìn thấy. Xin lỗi nếu điều này rõ ràng với bạn, xin đừng phạm tội. Tôi nghĩ tôi sẽ bắt đầu từ đây. Hãy kiên nhẫn với tôi và tôi sẽ giải thích tình hình định tuyến của bạn sẽ diễn ra như thế nào (nhiều hơn hoặc ít hơn).
URL bao gồm một vài phần khác nhau, mỗi phần cho biết trình duyệt của một bit thông tin cụ thể được yêu cầu để tải xuống tài nguyên mà người dùng đang cố gắng truy cập. Thông thường các tài nguyên mà bạn đang tìm kiếm đang tắt trên một máy chủ ở đâu đó và trình duyệt biết điều này vì các phần trong URL như 'giao thức' ('http:') và 'máy chủ' ('www.mydomain.com'), vì vậy nó đi đến máy chủ đó để tìm những gì bạn đang yêu cầu. Cũng có các tham số 'truy vấn' trong các URL cung cấp một số thông tin bổ sung cho máy chủ về một hành động cụ thể, như cụm từ tìm kiếm của truy vấn tìm kiếm. Sau các tham số truy vấn, đến 'băm'. Hàm băm là nơi ma thuật của các ứng dụng đơn lẻ xảy ra ... eh, tốt, loại .....
Đầu tiên một chút về băm. Khi bạn thêm '#' vào URL, trình duyệt sẽ giải thích thông tin xuất hiện sau khi nó là một số vị trí (phần tử) trong tài liệu hiện được hiển thị.Điều đó có nghĩa là, nếu bạn có một phần tử có 'id' của 'main' và bạn thêm '#main' vào cuối URL, như vậy: 'http: //www.example.com#main', trình duyệt sẽ 'cuộn' (thường là 'nhảy') vào đầu phần tử đó, để bạn có thể thấy nó. Tuy nhiên, hãy lưu ý rằng nếu bạn nhập 'http://www.example.com/#main' (với mã băm được tách ra khỏi URL bằng dấu gạch chéo) thì bạn sẽ buộc tải lại trang hoàn chỉnh và trình duyệt sẽ tìm cách tìm tệp bằng tên '#main' trên máy chủ (Tôi đặt cược nó không tìm thấy nó).
Các takeaway ở đây là trình duyệt sẽ không cố gắng để di chuyển ra khỏi tài liệu hiện nếu có một băm trong URL, ngoại trừ là tất nhiên trường hợp đề cập ở trên, và điều này là rất tốt vì đơn ứng dụng trang không muốn điều hướng khỏi trang hoặc yêu cầu tài liệu mới từ máy chủ. (Xem cách định tuyến khác với các ứng dụng một trang?)
Bây giờ, toàn bộ điều này về hàm băm không quan trọng đối với các ứng dụng một trang, vì bạn có thể tạo một ứng dụng mà không phải xử lý tất cả. Một loạt các trình xử lý nhấp chuột và thao tác DOM là tất cả những gì bạn cần thực sự ... Nhưng điều đó có nghĩa là người dùng sẽ không có cách nào chia sẻ liên kết đến các chế độ xem cụ thể trong ứng dụng của bạn. URL sẽ không bao giờ thay đổi và chúng tôi sẽ không bao giờ có thể điều hướng trực tiếp đến bất kỳ chế độ xem cụ thể nào. Chúng tôi luôn bắt đầu từ vị trí bắt đầu của ứng dụng, điều này có thể dễ dàng là một tình huống rất khó chịu.
Nếu ứng dụng một trang của bạn sẽ có các chế độ xem khác nhau và bạn muốn người dùng có thể điều hướng trực tiếp đến những người cụ thể thông qua dấu trang hoặc liên kết, thì bạn sẽ cần triển khai biểu mẫu định tuyến trên giao diện người dùng ngoài định tuyến mà bạn sẽ cần phải triển khai trên chương trình phụ trợ (định tuyến cho API dữ liệu, v.v.), có nghĩa là bạn sẽ cần phải sử dụng hàm băm.
Tôi không muốn tìm hiểu cách các khung công tác khác nhau thực hiện định tuyến trên giao diện người dùng, nhưng về cơ bản là cập nhật trường địa chỉ của trình duyệt khi người dùng nhấp vào liên kết và xem thanh địa chỉ để xác định URL hiện tại và đang tải HTML được liên kết với URL đó vào DOM trong vị trí được chỉ định trong cây tài liệu. Vì vậy, trong một ứng dụng một trang, bạn có một tuyến đường trên máy chủ giao dịch với hiển thị tài liệu HTML ứng dụng (index.html) và bạn có các tuyến đường chịu trách nhiệm xử lý dữ liệu ứng dụng của bạn (tạo các cá thể mới trong cơ sở dữ liệu, đăng nhập và đăng xuất, chỉnh sửa hoặc hủy các cá thể trong DB và tìm nạp dữ liệu ...) được gọi thông qua các yêu cầu AJAX. Đây thực sự là một tình huống khá phức tạp trong HTML5 cho phép chúng tôi có thể từ bỏ băm (với sự giúp đỡ của một số liên kết viết lại trên máy chủ) và cũng có thể sử dụng các nút 'quay lại' và 'tiến lên' như thể chúng tôi đã thực sự điều hướng khỏi tài liệu gốc (mà chúng tôi chưa có vì chúng tôi chỉ chỉ trình duyệt đến cùng một URL, chỉ với các giá trị băm đã sửa đổi, vì vậy không có tải trang mới nào xảy ra). Điều hướng trang web truyền thống và liên kết có thể đạt được bằng cách sử dụng API lịch sử của trình duyệt, có sẵn cho IE bắt đầu với phiên bản 10 (tôi tin), phần còn lại của các nhà cung cấp trình duyệt lớn đã được sử dụng khá sớm trước đó, vì vậy công nghệ này sẽ cho phép người dùng điều hướng ứng dụng của bạn mà không có hàm băm trong URL. Giải thích điều này là một sự chuyển hướng và không cần thiết cho việc tìm hiểu định tuyến trong các ứng dụng một trang, nhưng điều đó thật thú vị và bạn sẽ phải học nó cuối cùng, có lẽ ..
AJAX nên được sử dụng để yêu cầu JSON từ máy chủ. Các yêu cầu AJAX sẽ luôn truy cập vào máy chủ của bạn vì bạn không bao gồm biểu tượng băm trong các yêu cầu AJAX (nó sẽ vô lý khi thực hiện vì băm chỉ có nghĩa là duyệt trong tài liệu), vì vậy các tuyến phía máy chủ phải chịu trách nhiệm cho việc lộ API dữ liệu của bạn (xem xét một RESTful). Mặc dù đây không phải là mục đích duy nhất của họ trong các ứng dụng một trang, nó có lẽ là mục đích quan trọng nhất của họ.
Soooo, để kết thúc, bạn sẽ có hai bộ tuyến đường. Một trên máy khách (như là một phần của một khung công tác phía khách như AngularJS hoặc EmberJS, danh sách tiếp tục ... Tôi thích Angular, nhưng có một đường cong học tập khá dốc.) Và một trên máy chủ. Khi bạn nghĩ về 'các tuyến máy chủ', hãy nghĩ rằng API dữ liệu. Khi bạn nghĩ đến 'định tuyến trang', hãy nhớ rằng tất cả điều này được xử lý trên máy khách, bằng javascript mà bạn đã gửi với phản hồi máy chủ ban đầu (đây là tuyến đường phía máy chủ cần thiết duy nhất có liên quan đến hiển thị HTML cho trình duyệt, tải 'index.html' của bạn và tất cả các tập lệnh và bảng định kiểu cần thiết, v.v.). Bạn sẽ sử dụng phần mềm trung gian express.static để phục vụ các tệp tĩnh, do đó bạn không phải lo lắng về việc chỉ định các tuyến cho công cụ đó.
EDIT Một đề cập nhanh về triển khai AJAX. Trên máy chủ, bạn sẽ có các tuyến tương tự như Alex đã cung cấp làm ví dụ và bạn sẽ thực hiện cuộc gọi tới các URL đó từ ứng dụng khách sử dụng bất kỳ đối tượng XMLHttpRequest (XHR) nào được hiển thị bởi khung hoặc thư viện bạn chọn. Hiện nay, nó được coi là thực hành tiêu chuẩn và tốt nhất cho các khuôn khổ/thư viện để thực hiện những yêu cầu này như Promises http://wiki.commonjs.org/wiki/Promises/A. Bạn nên đọc một chút về nó một mình, nhưng tôi có thể tóm tắt nó bằng cách nói rằng nó là một hoạt động không đồng bộ tương tự như 'try, catch, throw' trong các hoạt động đồng bộ. Bạn sẽ khởi tạo một đối tượng lời hứa và thông qua nó, bạn sẽ cố gắng tải dữ liệu từ máy chủ, ví dụ, thông qua yêu cầu GET. Đảm bảo rằng bạn đã gán các hàm để xử lý các yêu cầu được thực hiện cho URL mà bạn đã thực hiện yêu cầu (tuyến đường phía máy chủ)! Đối tượng này mà bạn khởi tạo và sau đó thực hiện yêu cầu đến máy chủ thông qua, hứa hẹn trả về kết quả của yêu cầu cho bạn khi nó trở lại từ máy chủ (cho dù nó thành công hay không) Nếu thành công, nó sẽ gọi một hàm mà bạn đã viết và sẽ cung cấp nó với dữ liệu từ máy chủ. Nếu nó không thành công, nó sẽ gọi một hàm khác, cũng được viết bởi bạn, và sẽ cung cấp nó với đối tượng lỗi (hoặc 'lý do' cho thất bại), để bạn có thể xử lý lỗi một cách thích hợp.
Hy vọng rằng sẽ giúp trả lời câu hỏi của bạn.
Mặc dù bạn có thể phục vụ một trang cho khách hàng, sẽ có nhiều tài nguyên khác mà bộ định tuyến ứng dụng của bạn sẽ xử lý, tệp CSS bên ngoài, JS, hình ảnh, tệp âm thanh/video, mẫu và tất nhiên REST của bạn hoặc các điểm cuối RPC tùy chỉnh mà ứng dụng một trang của bạn sẽ gọi để tìm nạp dữ liệu. – cbayram
Không quá quen thuộc với diễn đạt, nhưng hãy kiểm tra câu hỏi này http://stackoverflow.com/questions/12695591/node-js-express-js-how-does-app-router-work – cbayram
để lấy JSON trở lại mã máy khách, ví dụ để lấy danh sách sách, tôi vẫn định tuyến/sách ngay cả ứng dụng là trang đơn? – reza