Mã được lưu trữ từ xa (RHC) là tên gọi của Cửa hàng Chrome trực tuyến đối với mọi thứ được trình duyệt thực thi và được tải từ một nơi khác ngoài các tệp của chính tiện ích. Chẳng hạn như JavaScript và WASM. Nó không bao gồm dữ liệu hoặc những thứ như JSON hoặc CSS.
Tại sao RHC không còn được phép nữa?
Với Manifest V3, các tiện ích hiện cần phải gói tất cả mã mà chúng đang sử dụng bên trong chính tiện ích đó. Trước đây, bạn có thể chèn thẻ tập lệnh một cách linh động từ bất kỳ URL nào trên web.
Tôi được thông báo rằng tiện ích của tôi có RHC. Nội dung có vấn đề gì?
Nếu tiện ích của bạn bị từ chối trong quá trình xem xét do lỗi Blue Argon, thì tức là nhóm xem xét của chúng tôi cho rằng tiện ích của bạn đang sử dụng mã được lưu trữ từ xa. Đây thường là kết quả của một tiện ích tìm cách thêm thẻ tập lệnh bằng một tài nguyên từ xa (tức là từ web mở, thay vì các tệp có trong tiện ích), hoặc tìm nạp một tài nguyên để thực thi trực tiếp.
Cách nhận biết RHC
Việc phát hiện RHC không quá khó nếu bạn biết cần tìm những gì. Trước tiên, hãy kiểm tra các chuỗi "http://" hoặc "https://" trong dự án của bạn. Nếu có lỗi vi phạm về nội dung gây hại cho trẻ em, thì bạn có thể tìm thấy lỗi đó. Nếu bạn có một hệ thống xây dựng đầy đủ hoặc sử dụng các phần phụ thuộc từ npm hoặc các nguồn bên thứ ba khác, hãy đảm bảo rằng bạn đang tìm kiếm phiên bản đã biên dịch của mã, vì đó là phiên bản được cửa hàng đánh giá. Nếu bạn vẫn không tìm được vấn đề, thì bước tiếp theo là liên hệ với One Stop Support (Nhóm hỗ trợ tập trung). Họ có thể nêu rõ các lỗi vi phạm cụ thể và những việc cần làm để xuất bản tiện ích càng sớm càng tốt.
Việc cần làm nếu một thư viện yêu cầu mã
Bất kể mã đến từ đâu, bạn đều không được phép có RHC. Điều này bao gồm cả mã mà bạn không tạo, nhưng chỉ sử dụng làm phần phụ thuộc trong dự án của mình. Một số nhà phát triển sử dụng Firebase gặp phải vấn đề này khi mã từ xa được đưa vào để sử dụng trong Firebase Auth. Mặc dù đây là thư viện của bên thứ nhất (tức là do Google sở hữu), nhưng không có trường hợp ngoại lệ nào cho RHC. Bạn cần định cấu hình mã để xoá RHC hoặc cập nhật dự án để không bao gồm mã ngay từ đầu. Nếu bạn gặp phải vấn đề không phải do mã của bạn đang tải RHC, mà là do một thư viện bạn đang sử dụng, thì cách tốt nhất là liên hệ với tác giả của thư viện đó. Thông báo cho họ biết rằng vấn đề này đang xảy ra và yêu cầu họ đưa ra giải pháp hoặc cập nhật mã để xoá vấn đề.
Điều gì xảy ra nếu bạn không thể chờ bản cập nhật thư viện
Một số thư viện sẽ gửi bản cập nhật gần như ngay lập tức sau khi nhận được thông báo, nhưng những thư viện khác có thể bị bỏ rơi hoặc mất thời gian để giải quyết vấn đề. Tuỳ thuộc vào nội dung trong lỗi vi phạm cụ thể, bạn có thể không cần đợi đến khi lỗi vi phạm đó được gỡ bỏ và hoàn tất quy trình xem xét thành công. Có một số lựa chọn để bạn có thể nhanh chóng khôi phục và hoạt động trở lại.
Kiểm tra mã
Bạn có chắc chắn rằng cần có mã gây ra yêu cầu này không? Nếu bạn chỉ cần xoá hoặc có thể xoá một thư viện đang gây ra vấn đề này, thì hãy xoá mã đó và công việc sẽ hoàn tất.
Hoặc có thư viện nào khác cung cấp các tính năng tương tự không? Hãy thử kiểm tra npmjs.com, GitHub hoặc các trang web khác để tìm những lựa chọn khác đáp ứng các trường hợp sử dụng tương tự.
Lắc cây
Nếu mã gây ra lỗi vi phạm RHC không thực sự được sử dụng, thì công cụ có thể tự động xoá mã đó. Các công cụ xây dựng hiện đại như webpack, Rollup và Vite (chỉ là một vài ví dụ) có một tính năng gọi là tree-shaking (loại bỏ mã không dùng đến). Sau khi được bật trên hệ thống xây dựng, tính năng loại bỏ mã không dùng đến sẽ xoá mọi đường dẫn mã không dùng đến. Điều này có nghĩa là bạn không chỉ có một phiên bản tuân thủ hơn của mã mà còn có một phiên bản tinh gọn và nhanh hơn! Điều quan trọng cần lưu ý là không phải thư viện nào cũng có thể được loại bỏ các phần không dùng đến, nhưng nhiều thư viện có thể. Một số công cụ, chẳng hạn như Rollup và Vite, được bật tính năng loại bỏ mã không dùng đến theo mặc định. Bạn cần định cấu hình webpack để bật tính năng này. Nếu không sử dụng hệ thống xây dựng trong phần mở rộng của mình, nhưng có sử dụng các thư viện mã, thì bạn thực sự nên tìm hiểu cách thêm một công cụ xây dựng vào quy trình làm việc của mình. Các công cụ Build giúp bạn viết các dự án an toàn, đáng tin cậy và dễ bảo trì hơn.
Thông tin cụ thể về cách triển khai tính năng loại bỏ mã không dùng đến phụ thuộc vào dự án cụ thể của bạn. Nhưng để lấy một ví dụ đơn giản với Rollup, bạn có thể thêm tính năng loại bỏ mã không dùng đến chỉ bằng cách biên dịch mã dự án của mình. Ví dụ: nếu bạn có một tệp chỉ đăng nhập vào Firebase Auth, có tên là main.js:
import { GoogleAuthProvider, initializeAuth } from "firebase/auth"; chrome.identity.getAuthToken({ 'interactive': true }, async (token) => { const credential = GoogleAuthProvider.credential(null, token); try { const app = initializeApp({ ... }); const auth = initializeAuth(app, { popupRedirectResolver: undefined, persistence: indexDBLocalPersistence }); const { user } = await auth.signInWithCredential(credential) console.log(user) } catch (e) { console.error(error); } });
Sau đó, bạn chỉ cần cho Rollup biết tệp đầu vào, một trình bổ trợ cần thiết để tải các tệp nút @rollup/plugin-node-resolve và tên của tệp đầu ra mà trình bổ trợ này đang tạo.
npx rollup --input main.js --plugin '@rollup/plugin-node-resolve' --file compiled.js
Khi chạy lệnh đó trong cửa sổ dòng lệnh, bạn sẽ nhận được một phiên bản đã tạo của tệp main.js, tất cả được biên dịch thành một tệp duy nhất có tên là compiled.js.
Rollup có thể đơn giản nhưng cũng rất dễ định cấu hình. Bạn có thể thêm mọi loại logic và cấu hình phức tạp, chỉ cần xem tài liệu của chúng. Việc thêm các công cụ tạo bản dựng như thế này sẽ giúp mã nhỏ hơn, hiệu quả hơn và trong trường hợp này, sẽ khắc phục vấn đề về mã được lưu trữ từ xa.
Tự động chỉnh sửa tệp
Một cách ngày càng phổ biến để mã được lưu trữ từ xa có thể xâm nhập vào cơ sở mã của bạn là dưới dạng một phần phụ thuộc của thư viện mà bạn đang đưa vào. Nếu thư viện X muốn import thư viện Y từ CDN, thì bạn vẫn cần cập nhật thư viện đó để thư viện tải từ một nguồn cục bộ. Với các hệ thống bản dựng hiện đại, bạn có thể dễ dàng tạo các trình bổ trợ để trích xuất một tham chiếu từ xa và chèn trực tiếp tham chiếu đó vào mã của mình.
Điều đó có nghĩa là mã đã cho sẽ có dạng như sau:
import moment from "https://unpkg.com/moment@2.29.4/moment.js" console.log(moment())
Bạn có thể tạo một trình bổ trợ rollup nhỏ.
import { existsSync } from 'fs'; import fetch from 'node-fetch'; export default { plugins: [{ load: async function transform(id, options, outputOptions) { // this code runs over all of out javascript, so we check every import // to see if it resolves as a local file, if that fails, we grab it from // the network using fetch, and return the contents of that file directly inline if (!existsSync(id)) { const response = await fetch(id); const code = await response.text(); return code } return null } }] };
Sau khi bạn chạy bản dựng bằng trình bổ trợ mới, mọi URL import từ xa sẽ được phát hiện bất kể đó có phải là mã, một phần phụ thuộc, phần phụ thuộc con hoặc bất kỳ nơi nào khác của chúng tôi hay không.
npx rollup --input main.js --config ./rollup.config.mjs --file compiled.js
Chỉnh sửa tệp theo cách thủ công
Cách đơn giản nhất là chỉ cần xoá mã gây ra RHC. Mở tệp này trong trình chỉnh sửa văn bản mà bạn chọn, rồi xoá các dòng vi phạm. Điều này thường không được khuyến khích vì dễ bị quên và có thể bị bỏ qua. Việc duy trì dự án của bạn sẽ khó khăn hơn khi một tệp có tên "library.min.js" thực sự không phải là library.min.js. Thay vì chỉnh sửa các tệp thô, bạn có thể sử dụng một công cụ như patch-package để dễ bảo trì hơn một chút. Đây là một lựa chọn cực kỳ mạnh mẽ, cho phép bạn lưu các nội dung sửa đổi vào một tệp, thay vì lưu chính tệp đó. Thư viện này được xây dựng trên các tệp vá, cùng loại với những tệp hỗ trợ các hệ thống quản lý phiên bản như Git hoặc Subversion. Bạn chỉ cần sửa đổi mã vi phạm theo cách thủ công, lưu tệp chênh lệch và định cấu hình patch-package bằng những thay đổi mà bạn muốn áp dụng. Bạn có thể đọc hướng dẫn đầy đủ trên README của dự án. Nếu đang vá một dự án, bạn thực sự nên liên hệ với dự án đó để yêu cầu thực hiện các thay đổi ở nguồn. Mặc dù patch-package giúp việc quản lý các bản vá dễ dàng hơn rất nhiều, nhưng không cần vá lỗi vẫn là điều tốt nhất.
Việc cần làm nếu mã không được sử dụng
Khi cơ sở mã tăng lên, các phần phụ thuộc (hoặc phần phụ thuộc của một phần phụ thuộc, hoặc phần phụ thuộc của...) có thể giữ lại các đường dẫn mã không còn được sử dụng nữa. Nếu một trong những phần đó có chứa mã để tải hoặc thực thi RHC, thì bạn sẽ phải xoá mã đó. Dù pin đã hết hay chưa dùng đến thì bạn vẫn cần phải tháo pin. Nếu không được sử dụng, bạn nên xoá thư viện này bằng cách loại bỏ các phần không dùng đến hoặc vá thư viện để xoá thư viện này.
Có giải pháp nào không?
Nói chung là không. Bạn không được sử dụng RHC. Tuy nhiên, có một số ít trường hợp được phép. Đây hầu như luôn là những trường hợp không thể dùng lựa chọn nào khác.
User Scripts API
User Scripts (Tập lệnh người dùng) là những đoạn mã nhỏ thường do người dùng cung cấp, dành cho các trình quản lý User Script như TamperMonkey và Violentmonkey. Các trình quản lý này không thể kết hợp mã do người dùng viết, vì vậy User Script API cung cấp một cách để thực thi mã do người dùng cung cấp. Đây không phải là giải pháp thay thế cho chrome.scripting.executeScript hoặc các môi trường thực thi mã khác. Người dùng phải bật chế độ nhà phát triển để thực hiện mọi thao tác. Nếu nhóm đánh giá của Cửa hàng Chrome trực tuyến cho rằng tiện ích này đang được sử dụng theo cách khác với mục đích dự kiến (tức là mã do người dùng cung cấp), thì tiện ích này có thể bị từ chối hoặc trang thông tin của tiện ích này có thể bị gỡ bỏ khỏi cửa hàng.
chrome.debugger
API chrome.debugger cho phép các tiện ích tương tác với Giao thức Chrome DevTools. Đây cũng là giao thức được dùng cho Công cụ cho nhà phát triển của Chrome và rất nhiều công cụ khác. Với công cụ này, một tiện ích có thể yêu cầu và thực thi mã từ xa. Giống như tập lệnh người dùng, tiện ích này không thay thế cho chrome.scripting và mang lại trải nghiệm người dùng đáng chú ý hơn nhiều.
Trong khi sử dụng, người dùng sẽ thấy một thanh cảnh báo ở đầu cửa sổ. Nếu biểu ngữ bị đóng hoặc bị loại bỏ, phiên gỡ lỗi sẽ bị chấm dứt.
Iframe có thuộc tính hộp cát
Nếu bạn cần đánh giá một chuỗi dưới dạng mã và đang ở trong môi trường DOM (ví dụ: tập lệnh nội dung, thay vì trình chạy dịch vụ của tiện ích), thì một lựa chọn khác là sử dụng iframe được cách ly. Theo mặc định, các tiện ích không hỗ trợ những thứ như eval() để đảm bảo an toàn. Mã độc có thể gây rủi ro cho sự an toàn và bảo mật của người dùng. Nhưng khi mã chỉ được thực thi trong một môi trường an toàn đã biết, chẳng hạn như iframe đã được cách ly khỏi phần còn lại của web, thì những rủi ro đó sẽ giảm đi đáng kể. Trong bối cảnh này, Chính sách bảo mật nội dung chặn việc sử dụng eval có thể được gỡ bỏ, cho phép bạn chạy mọi mã JavaScript hợp lệ.
Nếu bạn có một trường hợp sử dụng không được đề cập, hãy liên hệ với nhóm bằng danh sách gửi thư chromium-extensions để nhận ý kiến phản hồi hoặc mở một phiếu yêu cầu mới để yêu cầu hướng dẫn từ Dịch vụ hỗ trợ tập trung
Việc cần làm nếu bạn không đồng ý với phán quyết
Việc thực thi chính sách có thể phức tạp và quy trình xem xét có sự tham gia của con người. Điều này có nghĩa là đôi khi nhóm Cửa hàng Chrome trực tuyến có thể đồng ý thay đổi quyết định xem xét. Nếu cho rằng quyết định từ chối là do nhầm lẫn trong quá trình xem xét, bạn có thể kháng nghị quyết định đó thông qua One Stop Support