📋 目錄
這是 TC39 新語法深度解析系列的第十篇。Import Attributes(以前叫做 Import Assertions)解決了一個長期被忽視的安全問題:MIME-type confusion 攻擊。這個語法現在已進入 ES2024,所有主流瀏覽器都已支援。
Import Attributes 是什麼?
// 過去:不知道這個 JSON 是真的 JSON
import data from './data.json'; // 只知道副檔名是 .json
// 現在:明確宣告類型,讓瀏覽器驗證
import data from './data.json' with { type: 'json' };
with { type: 'json' } 告訴瀏覽器:「我預期這個模組的 MIME type 是 application/json」。如果伺服器返回的 Content-Type 不匹配,JavaScript 引擎會拒絕執行,而不是可能執行攻擊者構造的惡意內容。
為什麼這件事重要:MIME-type Confusion 攻擊
攻擊情境:
1. 攻擊者上傳一個看起來像 JSON 的恶意檔案(副檔名 .json)
2. 伺服器錯誤地將其 Content-Type 設為 application/javascript
3. 瀏覽器執行了惡意代碼,因為只看 Content-Type
Import Attributes 的防範:
import malicious from './data.json' with { type: 'json' };
瀏覽器會檢查 Content-Type 是否為 application/json,如果不是就拒絕執行
動態 import 的屬性語法
// 動態 import 也可以加屬性
const data = await import('./data.json', {
with: { type: 'json' }
});
// 或
const css = await import('./theme.css', {
with: { type: 'css' }
});
CSS Module Scripts:瀏覽器原生 CSS import
<!-- 在 HTML 中直接使用 CSS import -->
<script type="module">
const sheet = await import('./theme.css', {
with: { type: 'css' }
});
// sheet.default 是 CSSStyleSheet 物件
document.adoptedStyleSheets = [sheet.default];
</script>
Vite 與 webpack 的支援
// Vite 4.6+ 原生支援
import data from './data.json' with { type: 'json' };
// webpack 5+ 原生支援
import data from './data.json' with { type: 'json' };
Bundler 在打包時會幫你處理屬性驗證,讓這個語法在 development 和 production 都安全。
未來:更多類型
// 未來可能支援的類型
import wasm from './module.wasm' with { type: 'webassembly' };
import html from './widget.html' with { type: 'html' };
總結
Import Attributes 是那種「看起來很小的語法,但其實解決了一個重要安全問題」的功能:
- 所有瀏覽器現在都支援(ES2024)
- 開發體驗不變:Bundler 讓語法在 development 和 production 都安全
- 讓模組來源更明確:不再只依賴副檔名
這是 TC39 新語法深度解析系列的第十篇。
延伸閱讀
- TypeScript 6.0 RC 升級指南 — 支援 Import Attributes 新語法
本文基於 ES2024 Import Attributes(Stage 4)整理。