基於瀏覽器的 JavaScript 遊樂場可以在隔離的 Web Worker 中執行受限制的程式碼片段,取代需要 API 的工具,無需 API 金鑰、無需註冊,也無需網路存取。JavaScript 遊樂場在獨特來源且封鎖網路的沙箱中,以時間限制的 worker 執行簡短的 JavaScript 片段,所有輸出都會在同一個分頁中擷取。程式碼永遠不會離開你的電腦,每次執行時沙箱都會重新建立,而 1,500 毫秒的牆鐘時間限制會強制結束任何拒絕退出的迴圈。主控台訊息、傳回值和擲回的錯誤都會顯示在輸出面板中,因此你可以不離開頁面就檢視結果。這讓它成為依賴伺服器端執行 API、帳號或身分驗證權杖之遊樂場的實用替代方案。它的設計目的是用於語言實驗、演算法草稿、正則表達式檢查以及快速的資料結構檢查,而不是完整應用程式或任何涉及 DOM、網路或 Node.js 內建模組的東西。

javascript playground api alternative
瀏覽器測試的 JavaScript 遊樂場 API 替代方案

基於 API 的 JavaScript 遊樂場的不足之處

大多數託管的 JavaScript 遊樂場依賴後端執行服務。你將程式碼貼到瀏覽器編輯器中,編輯器透過 HTTPS 將原始碼傳送到遠端端點,該端點在伺服器上啟動容器或無伺服器函式,結果透過 websocket 或輪詢通道串流回來。這種架構可解鎖完整的 Node.js 存取和長時間執行程序,但它也引入了一堆使用者必須先滿足才能執行第一個片段的需求。

這種摩擦通常出現在同樣的五個地方:

  • API 金鑰或帳號。伺服器端執行需要計費、速率限制和身分驗證權杖,因此遊樂場會限制匿名使用。
  • 外傳的網路呼叫。你的原始文字會離開瀏覽器,這使得工作流程不適合包含專屬邏輯、客戶資料或未公開功能程式碼的片段。
  • 延遲。從編輯器到容器再來回的往返時間會累積,特別是對於答案應該幾乎立即出現的簡短片段。
  • 服務可用性。遊樂場的可達性取決於其後端,中斷、配額耗盡或 API 版本漂移都可能破壞你以為在本機的工作流程。
  • 狀態存放在別人的資料庫中。許多託管的遊樂場預設會保存片段、fork 和修訂,這會使合規審查變得複雜,並增加資料保留的工作量。

瀏覽器本機的遊樂場消除了上述清單中的每一項。腳本在你輸入它的同一個分頁中執行,結果出現在編輯器旁邊,完全不涉及瀏覽器以外的基礎架構。

瀏覽器本機沙箱如何取代 API

JavaScript 遊樂場實作了基於 API 的服務通常在其伺服器上強制執行的隔離合約,但完全使用瀏覽器原語來達成。每次執行都從一個全新的 iframe 開始,該 iframe 使用 sandbox="allow-scripts" 屬性和獨特的不透明來源建立。iframe 的內容安全策略預設拒絕所有資源,透過 connect-src 'none' 封鎖所有網路連線,並停用基礎 URL 和表單動作。iframe 允許執行腳本和啟動以 Blob 支援的 Web Worker,但它無法導覽父頁面、開啟彈出視窗、提交表單,或讀取父頁面的 cookie 和儲存空間。sandbox 屬性本身記載於 MDN iframe sandbox 參考資料中。

你的原始文字在插入 iframe 之前會先進行 JSON 編碼,並跳脫所有小於字元,使得包含結束 </script> 標籤的字串常值無法從其容器中逃逸。一旦引導程式執行,你的程式碼就會載入 Web Worker,這才是實際執行的地方。worker 沒有 DOM、document、window、localStorage、cookie,也沒有 session storage。它無法呼叫 fetch,因為 CSP 禁止網路連線,而且也沒有套件執行環境可供匯入。

輸出透過 postMessage 回傳。在接受任何訊息之前,父頁面會檢查三件事:訊息來自預期的 iframe 視窗、來源標記符合啟動它的執行階段、且每次執行的權杖符合為該執行階段產生的加密值。如果這些檢查中有任何一項失敗,該訊息就會被捨棄。獨特來源、JSON 插入的原始碼和三重檢查的訊息傳遞這三者的組合,正是讓沙箱無需伺服器就能安全使用的關鍵。

在 JavaScript 遊樂場中執行片段

  1. 在瀏覽器中開啟 JavaScript 遊樂場。編輯器最多接受 30,000 個字元,啟動時為空白或包含一個小型的起始片段。
  2. 輸入不需要 DOM、網路或 Node.js API 的受限制 JavaScript 片段。僅使用陣列、字串、物件、算術、正則表達式和語言實驗。
  3. 選擇執行 JavaScript。將建立一個全新的獨特來源 iframe 和 Web Worker,並為此次執行產生一個新的加密權杖。
  4. 檢閱主控台、結果、錯誤或逾時面板。console.log 和 console.error 輸出會以個別項目顯示,最終運算式在可以格式化時會被回報為結果。
  5. 編輯原始碼並再次執行。每次執行都會取代先前的沙箱,因此先前執行的剩餘狀態無法洩漏到下一次執行中。

沙箱允許和拒絕的內容

功能沙箱中的狀態
純 JavaScript 運算允許
console.log 和 console.error擷取並顯示在輸出面板中
最終運算式作為傳回值在可能的情況下以格式化結果回報
Promise 和 async / await在 Promise 解決或逾時結束 worker 之前允許
DOM 存取 (document, window)拒絕 — worker 沒有 DOM 繫結
fetch、XMLHttpRequest 或任何網路呼叫拒絕 — CSP 封鎖所有網路連線
套件匯入或 Node.js 內建模組拒絕 — 未提供模組載入器
localStorage、cookie、session storage拒絕 — worker 沒有儲存 API
持續性專案或檔案儲存拒絕 — 每次執行都從全新的沙箱開始
長時間執行的迴圈在 1,500 毫秒時終止

拒絕清單就是安全性模型。將沙箱視為防禦邊界,而不是執行你尚未審閱之片段的綠燈。任何線上編輯器,包括這個在內,都不是處理密碼、API 金鑰、工作階段權杖、客戶資料或專屬原始碼的適當場所。

適合 1.5 秒時間窗的用途

1,500 毫秒的上限對於短小、確定性的片段綽綽有餘,但對於迴圈處理大型輸入的任何內容來說則很緊迫。遠在預算內就能完成的任務包括排序小型陣列、對映和篩選練習、使用 split 和 match 進行字串剖析、JSON 結構探索、算術健全性檢查,以及快速的正則表達式實驗。典型的用途是貼上一個棘手的正則表達式,確認特定輸入是否符合預期的擷取群組,然後再將該模式複製到專案中 — 這類檢查涵蓋於 如何在 JavaScript 中檢查正則表達式模式中。

通常不適合的任務包括任何處理數百萬列的內容、任何需要串流或分塊 I/O 的內容,以及任何依賴資料庫或遠端 API 的內容。如果片段需要 fetch 或匯入,沙箱將拒絕網路呼叫,無論時鐘上還剩下多少時間。

並列比較遊樂場方法

屬性瀏覽器本機沙箱 (JavaScript 遊樂場)託管的基於 API 遊樂場
需要 API 金鑰或註冊通常是
原始碼離開瀏覽器
使用者程式碼的網路存取由 CSP 封鎖可用
DOM 和 window API不可用在瀏覽器 iframe 中可用
Node.js 內建模組和套件未提供通常可用
執行位置同一分頁中的 Web Worker遠端容器或無伺服器函式
預設執行上限1,500 毫秒牆鐘時間依方案而異
持續性專案通常是
貼上前的程式碼審閱必要 — 沙箱是防禦邊界,不是惡意程式碼的沙箱同樣的責任適用

這兩欄解決的是不同的問題。如果你想評估語言行為、草擬演算法,或針對小型測試資料檢查正則表達式,瀏覽器本機沙箱消除了所有帳號和配額障礙。如果你需要多檔案專案、真實的 DOM 渲染,或伺服器端執行環境,託管的遊樂場才是正確的工具,你應該選擇一家你已閱讀過其安全性模型的供應商。

本機專案何時成為更好的工具

逾時是牆鐘時間防護,而不是效能基準。瀏覽器排程在不同的分頁和裝置之間有所不同,因此非同步工作即使在再過幾毫秒就會完成的情況下,仍可能會在邏輯上完成之前就被終止。對於生產程式碼,你仍然應該使用具有版本控制、本機測試、程式碼檢查、相依項目審閱以及實際執行該程式碼之執行環境的本機專案。遊樂場是用來回答單一問題的草稿區;儲存庫則是用來保存答案的地方。

執行程式碼片段之前先審閱它們,將沙箱視為防禦邊界,並將機密資料排除在編輯器之外。這三個習慣正是讓瀏覽器本機 JavaScript 遊樂場成為其設計目的之小型實驗的安全預設選擇的原因。

相關閱讀:在瀏覽器中本機執行的 JSON 轉 CSV API 替代方案