「批次」JavaScript Playground 工作階段會依序執行許多簡短且獨立的程式碼片段,每個片段都在一個全新的沙箱化 Worker 內執行,該 Worker 會在 1,500 毫秒後銷毀,並且永遠不會碰觸頁面的 DOM、cookie 或網路。編輯器每個片段最多接受 30,000 個字元的純 JavaScript,而每次點擊 Run JavaScript 都會從頭重建沙箱:產生新的密碼學隨機通道權杖、新的唯一來源 iframe 和新的 Web Worker,片段會以跳脫小於字元的方式進行 JSON 編碼,而且只有在訊息來源、固定標記和當前權杖三者全部相符時,結果才會被接受。這種模式把批次測試變成一個快速、可稽核的迴圈,而不是一連串共用狀態的佇列,因為每一次執行都是一張乾淨的空白頁。它是陣列、字串、正則表達式、解析和算術實驗的正確工具形態,卻是任何需要 DOM、window、fetch、套件或持久檔案的程式碼的錯誤工具形態。本文會逐步說明這種隔離機制的實際運作方式、如何使用 JavaScript Playground 進行批次片段迭代,以及每次批次執行必須遵守的限制。

javascript playground bulk
批次 JavaScript Playground 執行:安全地迭代程式碼片段

沙箱如何隔離每一次批次執行

每一次批次執行都從同樣的四個步驟設定開始,這正是讓重複迭代從一開始就安全的原因。Playground 會產生一個當前點擊專用、密碼學上隨機的權杖,以跳脫小於字元的方式將片段 JSON 編碼,使提交的程式碼中出現的結束 script 標籤無法從 iframe 的標記中脫逃,並建構一個允許執行腳本但封鎖同源存取、表單、導航、快顯視窗和下載的唯一來源 iframe。該 iframe 帶有一個預設拒絕的內容安全政策,會封鎖所有資源、拒絕所有網路連線、僅允許內嵌的啟動程式碼和 Blob worker,並停用基礎 URL 和表單動作。在該 iframe 內,片段實際上是執行在 Web Worker 中而非 UI 執行緒上,這就是為什麼失控的迴圈無法凍結上層頁面。經過 1,500 毫秒後,iframe 會終止該 Worker,而下一次點擊會將整個沙箱拆解並從零重建。Web Workers API 和 iframe sandbox 屬性的 MDN 參考文件記載了 Playground 所組合的同一組基本元素,而這些也是確認每次執行權杖、唯一來源或沙箱旗標任何細節的正確去處。

在 JavaScript Playground 中執行一批程式碼片段

單次執行的機制刻意保持精簡,讓執行多次的成本依然低廉。以下的有序步驟涵蓋迴圈的一次迭代;請依批次工作階段的需要重複執行。

  1. 開啟 JavaScript Playground 編輯器,貼上一段不需要 DOM、document、fetch、import 或 Node.js API 的有界純 JavaScript 片段。
  2. 點擊 Run JavaScript。頁面會建立一個全新的沙箱:唯一權杖、跳脫小於字元的 JSON 編碼 payload、唯一來源 iframe,以及專屬的 Worker。
  3. 讀取 console、結果、錯誤或逾時那一行。Console 會擷取 log 和 error 呼叫,當最終運算式可以格式化為 JSON 或字串時會回報為結果,如果程式碼沒有在 1,500 毫秒內結束則會產生逾時行。
  4. 編輯片段並再次點擊 Run JavaScript。舊的 iframe 會被取代、舊的權杖會被丟棄,來自上一次執行的所有狀態都會消失。
  5. 依工作階段的需要為多個片段重複以上步驟。Playground 不儲存任何專案、檔案或歷史紀錄,因此每一次批次迭代都是自包含的,且可以逐行檢閱。

Playground 接受什麼、封鎖什麼

以下的數字和行為是沙箱已發布的限制;它們在每次點擊時都相同,對每個片段也都相同。

屬性數值或行為
原始碼長度限制每個片段 30,000 個字元
執行模型唯一來源 iframe 內的 Web Worker
失控程式碼防護Worker 在 1,500 毫秒後(壁鐘時間)終止
網路存取由 CSP 封鎖(connect-src none 且無資源允許)
每次執行的通道權杖密碼學上隨機,每次點擊都會更換
訊息接受條件來源、固定標記和當前權杖必須全部相符
原始碼編碼JSON 編碼,並跳脫小於字元
執行之間的儲存無 — 沒有專案、檔案或持久狀態
匯入與套件未提供
DOM、document、window、localStorage、cookieWorker 中不存在

由於 Worker 沒有 DOM、document、window、localStorage、cookie 或頁面工作階段,且網路擷取被 CSP 封鎖,因此這個沙箱的形態是為語言與資料類工作而設計,而非瀏覽器 UI 程式碼。任何超出此範圍的事物都必須在其他地方測試。

適合批次測試工作階段的片段類別

以下類別是 Worker 確實能從頭到尾執行的類別;它們也是最能在不離開頁面的情況下連續執行多種變體而獲益最多的類別。

  • 陣列:排序、切片、去重、group-by、flat-map、分塊,以及在各種輸入上對同一運算的 reduce 變體。
  • 字串:修剪、以棘手分隔符號分割、大小寫轉換、跳脫、樣板組裝,以及 Unicode 正規化實驗。
  • 物件:深拷貝、深相等、pick 或 omit、合併,以及在許多小型樣本上的鍵重新命名。
  • 正則表達式:在把同一個正則表達式送進專案前,用來快速測試匹配、命名群組、replace 回呼和環顧模式的暫存介面。
  • 解析:用於 CSV 片段、日誌行或數字格式的小型臨時解析器,在多個樣本輸入上迭代比架設測試執行器更快。
  • 算術:四捨五入規則、BigInt 邊界、整數溢位檢查,以及需要一次對多個值進行嘗試的單位轉換。

上述每個類別都適合在編輯器中進行批次操作:貼上下一個變體、執行、讀取 console 與結果、貼上下一個變體、再次執行。由於 Playground 會在執行之間銷毀狀態,相同類別中的兩個片段不會意外地將變數洩漏給彼此。

迭代、比較、重複:批次工作流程

讓批次測試在這個工具中感覺快速的核心機制是「每次執行都重建」的模式。每次點擊 Run JavaScript 都會丟棄舊的 iframe、產生新的權杖、重新編碼片段,並重建 Worker,這代表當下一個片段拋出例外時,永遠不需要去推論上一次執行的狀態。這個特性在迭代演算法時最為有用:編輯器中放著一個可運作的基準,改動一行,再次執行程式碼,把新的結果行與基準比較,然後保留或退回該變更。由於 console 訊息、錯誤和最終運算式結果都會經過同一個來源—標記—權杖檢查,因此看到的輸出只會是剛執行的程式碼所產生的輸出。

一個實際演練的範例可以說明其形態。考慮把陣列 [1, 2, 3, 4, 5] 透過把每個元素加入從 0 開始的累加器,最終 reduce 成單一總和。代入數字後,步驟為 0 + 1 = 1,1 + 2 = 3,3 + 3 = 6,6 + 4 = 10,10 + 5 = 15,因此 Playground 回報的最終運算式結果為 15。那條單一的算術鏈 — 初始值、五次加法、一個回報的總和 — 就是一次批次執行的完整生命週期。換掉陣列、換掉函式,再次點擊 Run JavaScript,在下一次 reduce 開始前沙箱就會被重建。

貼上任何片段前的安全規則

沙箱是一道防禦邊界,而不是一張通行證。無論 iframe 是否被鎖定,請以同樣的方式對待每一個編輯器。

  • 絕不要將密碼、API 金鑰、工作階段權杖、OAuth 用戶端密鑰或任何其他長效期的憑證貼進編輯器。
  • 絕不要將私人客戶資料、個人識別資訊或專屬原始碼貼進 Playground。
  • 執行程式碼前請檢視片段。即使網路被封鎖、Worker 生命週期短暫,提交的邏輯仍然會在本機上執行。
  • 讓模擬的延遲保持簡短。在 1,500 毫秒壁鐘防護後到達的非同步日誌可能會被丟棄,因此基於計時器的實驗應完全落在逾時內,而非逼近逾時。
  • 對於任何將部署到正式環境的程式碼,請使用具備版本控制的本機專案,搭配測試、lint、依賴審查以及真正會執行該程式碼的執行階段。Playground 是用來迭代的,不是用來交付的。

JavaScript Playground 何時是、何時不是合適的批次工具

在下列情況使用 Playground在下列情況改用其他工具
演算法實驗與語言暫存工作片段需要 DOM、document、window 或瀏覽器 API
陣列、字串、物件、正則表達式和解析的變體程式碼依賴 fetch、import 或套件執行環境
算術、四捨五入和 BigInt 邊界檢查工作是具有檔案、測試和依賴的真實專案
快速基準 + 微調 + 重新執行的迴圈輸出必須持久、可分享或受版本控制
在不碰觸頁面的情況下對片段進行安全迭代片段需要 Node.js API、TypeScript 編譯或除錯中斷點

上述區分是性質上的,而非數值上的建議;確切的適用性取決於每個片段實際需要什麼。誠實的結論是,JavaScript Playground 被打造為在瀏覽器中執行有界片段最快的地方,而這個速度的刻意代價就是執行之間沒有任何東西會存活下來。

如果您正在權衡選項,批次 JSON 轉 CSV:限制與本機工作流程對此有詳細說明。

如果您正在權衡選項,JavaScript 按鍵代碼查詢工具:解碼 KeyboardEvent 欄位對此有詳細說明。