談談 JavaScript 中的 eval、風險及替代方案

前言最近用 Google Sheets 提供的 App Script 幫朋友寫了個小爬蟲,來自動化搬運跟整理網頁上資訊,發現 HTML Source 裡

在 App Script 中,可以用 UrlFetchApp.fetch 去 GET 一個 url,並用 getContentText 取得該頁面所有的 HTML Code。

再根據先前對於 HTML 結構的觀察,我們可以再透過正則表達式取得我們想要的程式碼段落。

let response = UrlFetchApp.fetch(youtubeUrl);

let pageSource = response.getContentText();

let jsCodeMatch = pageSource.match(/var ytInitialData = (\{[^]+?\});/);

接下來是不是只要再寫一次正則來 match 就可以取得我們要的資料了呢?

let titleMatch = pageSource.match(/title: '([^']+)'/);

let subscriberCountMatch = pageSource.match(/simpleText: '([^']+)'/);

很可惜地不行!

從上面的的 raw data 可以看到它是被包在

3. Node.js: isolated-vm透過 isolated-vm 這個套件可以在一個獨立的、與主線程隔離的虛擬機(virtual machine)中執行 JavaScript 程式碼,讓不信任的程式碼將在一個受到限制的環境中運行,就不會影響到原本的程式碼。

結語這篇文章剛寫好時,其實只包含了前兩個使用情境,並且對於 eval 的使用採取極端否定的態度,但其實仔細找還是有不少使用的情境,只要掌握觀念,分析好當前情境就可以使用,而對於 eval 的判斷依據就是「信不信任你要執行的 script」,以及避免 Never use eval()! 提到的效能問題。

會有這樣的轉變主要是分享到 Twitter 後,得到 Huli 提供 Vue devtools 和 Angular 的使用案例(Original Tweet)和 flandre 的建議,原本隨筆紀錄,然後以為沒什麼的東西意外延伸了很多知識挺有趣的,同時也非常感謝!

另外這次會接觸到 eval 是在 ChatGPT 上看到的,深感 ChatGPT 確實能擴充我對於「不知道的不知道(Unknown Unknown)」的知識邊界 ,但擴充了之後仍然需要去理解,因為它提供的解法雖然可以符合需求,但可能沒有考慮那麼多,也不一定會提供符合當前情境的最佳解,像這次就是提供 eval 的解法,但其實是可以使用更安全的 JSON.parse() 解法,在深入探討後,也發現了 eval 竟然可以應用在 dev tools 和 開發工具上,這算是完全沒想到的連結。

一言以蔽之,平常要多擴充自己的知識,來增加對於這些資訊的判斷力!

如果有人想補充或知道 eval 其他的使用情境,歡迎留言告訴我 🤩!