Cách tạo nhiều PWA, tận dụng cùng một tên miền để cho người dùng biết rằng các PWA đó thuộc cùng một tổ chức hoặc dịch vụ.
Trong bài đăng trên blog về Ứng dụng web tiến bộ trong các trang web có nhiều nguồn gốc, Demian đã thảo luận về những thách thức mà các trang web được xây dựng trên nhiều nguồn gốc gặp phải khi cố gắng tạo một Ứng dụng web tiến bộ duy nhất bao gồm tất cả các trang web đó.
Ví dụ về loại cấu trúc trang web này là một trang web thương mại điện tử, trong đó:
- Trang chủ có địa chỉ là
https://www.example.com
. - Các trang danh mục được lưu trữ tại
https://category.example.com
. - Trang chi tiết sản phẩm tại
https://product.example.com
.
Như đã thảo luận trong bài viết, chính sách cùng nguồn gốc áp đặt một số hạn chế, ngăn chặn việc chia sẻ trình chạy dịch vụ, bộ nhớ đệm và quyền trên các nguồn gốc. Vì lý do đó, bạn nên tránh loại cấu hình này và đối với những người đã có các trang web được xây dựng theo cách này, hãy cân nhắc việc di chuyển sang cấu trúc trang web có một nguồn gốc duy nhất bất cứ khi nào có thể.

Trong bài đăng này, chúng ta sẽ xem xét trường hợp ngược lại: thay vì một PWA duy nhất trên nhiều nguồn gốc, chúng ta sẽ phân tích trường hợp các công ty muốn cung cấp nhiều PWA, tận dụng cùng một tên miền và cho người dùng biết rằng những PWA đó thuộc cùng một tổ chức hoặc dịch vụ.
Như bạn có thể nhận thấy, chúng tôi đang sử dụng các thuật ngữ khác nhau nhưng có liên quan với nhau, chẳng hạn như miền và nguồn gốc. Trước khi tiếp tục, hãy xem lại những khái niệm này.
Thuật ngữ kỹ thuật
- Miền: Bất kỳ chuỗi nhãn nào như được xác định trong Hệ thống tên miền (DNS).
Ví dụ:
com
vàexample.com
là các miền. - Tên máy chủ: Một mục DNS phân giải thành ít nhất một địa chỉ IP. Ví dụ:
www.example.com
sẽ là một tên máy chủ,example.com
có thể là một tên máy chủ nếu có địa chỉ IP vàcom
sẽ không bao giờ phân giải thành một địa chỉ IP nên không bao giờ có thể là một tên máy chủ. - Nguồn gốc: Tổ hợp của một lược đồ, tên máy chủ và (không bắt buộc) cổng. Ví dụ:
https://www.example.com:443
là một nguồn.
Như tên gọi của nó, chính sách cùng nguồn gốc áp đặt các hạn chế đối với nguồn gốc, vì vậy, chúng ta sẽ chủ yếu đề cập đến thuật ngữ này trong suốt bài viết. Tuy nhiên, đôi khi chúng ta sẽ sử dụng "miền" hoặc "miền con" để mô tả kỹ thuật đang được sử dụng nhằm tạo ra các "nguồn gốc" khác nhau.
Trường hợp có nhiều PWA liên quan
Trong một số trường hợp, bạn có thể muốn tạo các ứng dụng độc lập nhưng vẫn xác định chúng thuộc cùng một tổ chức hoặc "thương hiệu". Việc sử dụng lại cùng một tên miền là một cách hay để thiết lập mối quan hệ đó. Ví dụ:
- Một trang web thương mại điện tử muốn tạo một trải nghiệm độc lập để người bán quản lý kho hàng, đồng thời đảm bảo họ hiểu rằng trải nghiệm này thuộc về trang web chính nơi người dùng mua sản phẩm.
- Một trang web tin tức thể thao muốn tạo một ứng dụng cụ thể cho một sự kiện thể thao lớn, cho phép người dùng nhận số liệu thống kê về các giải đấu yêu thích của họ thông qua thông báo và cài đặt ứng dụng đó dưới dạng một Ứng dụng web tiến bộ, đồng thời đảm bảo rằng người dùng nhận ra đó là một ứng dụng do công ty tin tức này tạo ra.
- Một công ty muốn tạo các ứng dụng trò chuyện, thư và lịch riêng biệt và muốn các ứng dụng này hoạt động như các ứng dụng riêng lẻ, gắn liền với tên của công ty.

Sử dụng các nguồn gốc riêng biệt
Phương pháp được đề xuất trong những trường hợp như thế này là mỗi ứng dụng riêng biệt về mặt khái niệm sẽ hoạt động trên nguồn gốc riêng.
Nếu muốn sử dụng cùng một tên miền trong tất cả các miền con, bạn có thể thực hiện việc đó bằng cách sử dụng miền con. Ví dụ: một công ty cung cấp nhiều ứng dụng hoặc dịch vụ trên Internet có thể lưu trữ một ứng dụng thư tại https://mail.example.com
và một ứng dụng lịch tại https://calendar.example.com
, đồng thời cung cấp dịch vụ chính của doanh nghiệp tại https://www.example.com
. Một ví dụ khác là một trang web thể thao muốn tạo một ứng dụng độc lập hoàn toàn dành riêng cho một sự kiện thể thao quan trọng, chẳng hạn như một giải vô địch bóng đá tại https://footballcup.example.com
. Người dùng có thể cài đặt và sử dụng ứng dụng này độc lập với trang web thể thao chính, được lưu trữ tại https://www.example.com
. Phương pháp này cũng có thể hữu ích cho những nền tảng cho phép khách hàng tự tạo các ứng dụng độc lập của riêng họ dưới thương hiệu của công ty.
Ví dụ: một ứng dụng cho phép người bán tạo PWA của riêng họ tại https://merchant1.example.com
, https://merchant2.example.com
, v.v.
Việc sử dụng các nguồn gốc khác nhau đảm bảo sự tách biệt giữa các ứng dụng. Điều này có nghĩa là mỗi ứng dụng có thể quản lý các tính năng trình duyệt khác nhau một cách độc lập, bao gồm:
- Khả năng cài đặt: Mỗi ứng dụng đều có Tệp kê khai riêng và mang đến trải nghiệm có thể cài đặt riêng.
- Bộ nhớ: Mỗi ứng dụng có bộ nhớ đệm, bộ nhớ cục bộ riêng và về cơ bản là tất cả các dạng bộ nhớ cục bộ trên thiết bị mà không chia sẻ với các ứng dụng khác.
- Service Worker: Mỗi ứng dụng có một service worker riêng cho các phạm vi đã đăng ký.
- Quyền: Quyền cũng được giới hạn theo nguồn gốc. Nhờ đó, người dùng sẽ biết chính xác dịch vụ mà họ đang cấp quyền và các tính năng như thông báo sẽ được phân bổ đúng cho từng ứng dụng.
Việc tạo ra mức độ cô lập như vậy là điều mong muốn nhất trong trường hợp sử dụng nhiều PWA độc lập, vì vậy, bạn nên dùng phương pháp này.
Nếu muốn chia sẻ dữ liệu cục bộ với nhau, các ứng dụng trên miền con vẫn có thể thực hiện việc này thông qua cookie hoặc cân nhắc đồng bộ hoá bộ nhớ thông qua một máy chủ cho các trường hợp nâng cao hơn.

Sử dụng cùng nguồn gốc
Cách thứ hai là tạo các PWA khác nhau trên cùng một nguồn gốc. Điều này bao gồm các trường hợp sau:
Đường dẫn không chồng chéo
Nhiều PWA hoặc "ứng dụng web" theo khái niệm, được lưu trữ trên cùng một nguồn gốc, với các đường dẫn không trùng lặp. Ví dụ:
https://example.com/app1/
https://example.com/app2/
Đường dẫn trùng lặp/lồng nhau
Nhiều PWA trên cùng một nguồn gốc, trong đó một PWA có phạm vi được lồng bên trong PWA còn lại:
https://example.com/
("ứng dụng bên ngoài")https://example.com/app/
("ứng dụng bên trong")
API trình chạy dịch vụ và định dạng tệp kê khai cho phép bạn thực hiện một trong những thao tác trên bằng cách sử dụng phạm vi ở cấp đường dẫn. Tuy nhiên, trong cả hai trường hợp, việc sử dụng cùng một nguồn gốc sẽ gây ra nhiều vấn đề và hạn chế. Nguyên nhân là do trình duyệt sẽ không hoàn toàn coi đây là các "ứng dụng" riêng biệt, do đó, bạn không nên sử dụng phương pháp này.

Trong phần tiếp theo, chúng ta sẽ phân tích chi tiết hơn về những thách thức này và những việc có thể làm nếu không thể sử dụng các nguồn gốc riêng biệt.
Thách thức đối với nhiều PWA có cùng nguồn gốc
Sau đây là một số vấn đề thực tế thường gặp ở cả hai phương pháp cùng nguồn:
- Bộ nhớ: Cookie, bộ nhớ cục bộ và mọi hình thức bộ nhớ cục bộ trên thiết bị đều được chia sẻ giữa các ứng dụng. Vì lý do đó, nếu người dùng quyết định xoá dữ liệu cục bộ cho một ứng dụng, thì thao tác này sẽ xoá tất cả dữ liệu từ nguồn; không có cách nào để thực hiện việc này cho một ứng dụng duy nhất. Xin lưu ý rằng Chrome và một số trình duyệt khác sẽ chủ động nhắc người dùng xoá dữ liệu cục bộ khi gỡ cài đặt một trong các ứng dụng và điều này cũng sẽ ảnh hưởng đến dữ liệu của các ứng dụng khác trên nguồn. Một vấn đề khác là các ứng dụng cũng sẽ phải chia sẻ hạn mức bộ nhớ. Điều này có nghĩa là nếu một trong hai ứng dụng chiếm quá nhiều dung lượng, ứng dụng còn lại sẽ bị ảnh hưởng tiêu cực.
- Quyền: Quyền của trình duyệt được liên kết với nguồn gốc. Điều đó có nghĩa là nếu người dùng cấp quyền cho một ứng dụng, thì quyền đó sẽ áp dụng đồng thời cho tất cả ứng dụng trên nguồn gốc đó. Điều này có vẻ là một điều tốt (không phải yêu cầu quyền nhiều lần), nhưng hãy nhớ rằng: nếu người dùng chặn quyền truy cập vào một ứng dụng, thì các ứng dụng khác sẽ không thể yêu cầu quyền đó hoặc sử dụng tính năng đó. Xin lưu ý rằng ngay cả khi bạn chỉ cần cấp quyền cho trình duyệt một lần cho mỗi nguồn gốc, thì bạn phải cấp quyền ở cấp hệ thống một lần cho mỗi ứng dụng, bất kể nhiều ứng dụng có trỏ đến cùng một nguồn gốc hay không.
- Chế độ cài đặt người dùng: Chế độ cài đặt cũng được đặt theo từng nguồn gốc. Ví dụ: nếu 2 ứng dụng có kích thước phông chữ khác nhau và người dùng muốn điều chỉnh mức thu phóng chỉ trong một ứng dụng để bù đắp cho kích thước phông chữ đó, thì họ sẽ không thể làm như vậy nếu không áp dụng chế độ cài đặt cho các ứng dụng khác.
Những thách thức này khiến chúng tôi khó khuyến khích phương pháp này. Tuy nhiên, nếu không thể sử dụng một nguồn gốc riêng biệt (ví dụ: một miền con), như đã thảo luận trong phần Sử dụng các nguồn gốc riêng biệt, trong số 2 lựa chọn cùng nguồn gốc mà chúng tôi đã trình bày, bạn nên sử dụng các đường dẫn không chồng chéo thay vì các đường dẫn chồng chéo/lồng nhau.
Như đã đề cập, những thách thức được thảo luận trong phần này đều có trong cả hai phương pháp cùng nguồn gốc. Trong phần tiếp theo, chúng ta sẽ tìm hiểu kỹ hơn về lý do khiến việc sử dụng các đường dẫn chồng chéo/lồng nhau là chiến lược ít được đề xuất nhất.
Các thách thức khác đối với đường dẫn chồng chéo/lồng nhau
Vấn đề khác với phương pháp đường dẫn chồng chéo/lồng nhau (trong đó https://example.com/
là ứng dụng bên ngoài và https://example.com/app/
là ứng dụng bên trong) là tất cả URL trong ứng dụng bên trong sẽ thực sự được coi là một phần của cả ứng dụng bên ngoài và ứng dụng bên trong.
Trên thực tế, điều này gây ra những vấn đề sau:
- Quảng bá lượt cài đặt: Nếu người dùng truy cập vào ứng dụng bên trong (ví dụ: trong trình duyệt web), khi ứng dụng bên ngoài đã được cài đặt trên thiết bị của người dùng, trình duyệt sẽ không hiển thị biểu ngữ quảng bá lượt cài đặt và sự kiện BeforeInstallPrompt sẽ không được kích hoạt. Lý do là trình duyệt sẽ kiểm tra và xem trang hiện tại có thuộc về một ứng dụng đã được cài đặt hay không, rồi kết luận rằng trang đó thuộc về một ứng dụng đã được cài đặt. Giải pháp cho vấn đề này là cài đặt ứng dụng bên trong theo cách thủ công (thông qua lựa chọn "Tạo lối tắt" trong trình đơn trình duyệt) hoặc cài đặt ứng dụng bên trong trước khi cài đặt ứng dụng bên ngoài.
- Thông báo và Badging API: Nếu ứng dụng bên ngoài đã được cài đặt nhưng ứng dụng bên trong chưa được cài đặt, thì thông báo và huy hiệu của ứng dụng bên trong sẽ được gán nhầm cho ứng dụng bên ngoài (đây là phạm vi bao quanh gần nhất của một ứng dụng đã cài đặt). Tính năng này hoạt động đúng cách trong trường hợp cả hai ứng dụng đều được cài đặt trên thiết bị của người dùng.
- Tính năng bắt đường liên kết: Ứng dụng bên ngoài có thể bắt các URL thuộc ứng dụng bên trong. Điều này đặc biệt dễ xảy ra nếu ứng dụng bên ngoài đã được cài đặt nhưng ứng dụng bên trong thì chưa. Tương tự, các đường liên kết trong ứng dụng bên ngoài liên kết đến ứng dụng bên trong sẽ không ghi nhận lượt nhấp vào đường liên kết trong ứng dụng bên trong, vì các đường liên kết này được coi là nằm trong phạm vi của ứng dụng bên ngoài. Ngoài ra, trên ChromeOS và Android, nếu các ứng dụng này được thêm vào Cửa hàng Play (dưới dạng Hoạt động web đáng tin cậy), ứng dụng bên ngoài sẽ thu thập tất cả các đường liên kết. Ngay cả khi ứng dụng bên trong được cài đặt, hệ điều hành vẫn cho phép người dùng chọn mở ứng dụng đó trong ứng dụng bên ngoài.
Kết luận
Trong bài viết này, chúng ta đã xem xét nhiều cách mà nhà phát triển có thể tạo nhiều Ứng dụng web tiến bộ có liên quan đến nhau trong cùng một miền.
Tóm lại, bạn nên sử dụng một nguồn gốc khác (ví dụ: bằng cách sử dụng miền con) để lưu trữ các PWA độc lập. Việc lưu trữ các ứng dụng này trong cùng một nguồn gốc sẽ gây ra nhiều thách thức, chủ yếu là do trình duyệt sẽ không hoàn toàn coi đây là các ứng dụng riêng biệt.
- Nguồn gốc riêng biệt: Nên dùng
- Cùng nguồn gốc, đường dẫn không trùng lặp: Không nên
- Cùng nguồn gốc, đường dẫn trùng lặp/lồng nhau: Tuyệt đối không nên dùng
Nếu không thể sử dụng các nguồn gốc khác nhau, bạn nên sử dụng các đường dẫn không chồng chéo (ví dụ: https://example.com/app1/
và https://example.com/app2/
) thay vì sử dụng các đường dẫn chồng chéo hoặc lồng nhau, chẳng hạn như https://example.com/
(cho ứng dụng bên ngoài) và https://example.com/app/
(cho ứng dụng bên trong).
Tài nguyên khác
Xin chân thành cảm ơn những đánh giá và đề xuất về kỹ thuật của: Joe Medley, Dominick Ng, Alan Cutter, Daniel Murphy, Penny McLachlan, Thomas Steiner và Darwin Huang
Ảnh chụp của Tim Mossholder trên Unsplash