重新認識 script 標簽:不只是寫 JavaScript 那么簡單

很多人以為 script 標簽只是用來寫 JavaScript 代碼的地方。這種理解沒錯,但并不完整。實際上,這個看似簡單的標簽背后隱藏著許多值得探索的細節(jié)。
腳本加載的兩種方式:async 與 defer
瀏覽器解析 html 文檔時,是從上到下一邊解析一邊渲染的。當遇到普通的 script 標簽時,它會暫停解析,直到腳本下載并執(zhí)行完成后才會繼續(xù)。這就是為什么我們通常把腳本放在 body 底部的原因。
不過,async 和 defer 屬性提供了更好的解決方案。
使用 defer 屬性的腳本會異步下載,但會等到整個頁面解析完成后,按照它們在文檔中出現(xiàn)的順序執(zhí)行。這意味著它不會阻塞頁面解析,又能保證執(zhí)行順序。
<scriptdefersrc="js/script1.js"></script>
<scriptdefersrc="js/script2.js"></script>async 屬性的腳本也是異步下載,但它會在下載完成后立即執(zhí)行,不保證執(zhí)行順序。這意味著如果多個腳本有依賴關系,使用 async 可能會導致錯誤。
<scriptasyncsrc="js/script1.js"></script>
<scriptasyncsrc="js/script2.js"></script>簡單來說,defer 適合需要按順序執(zhí)行且不急于執(zhí)行的腳本,而 async 適合獨立且需要盡快執(zhí)行的腳本,比如網(wǎng)站統(tǒng)計分析代碼。
跨域腳本處理:crossorigin 屬性
script 標簽可以加載跨域資源,JSONP 技術就是利用了這個特性。但隨著網(wǎng)絡安全要求的提高,crossorigin 屬性變得越來越重要。
設置 crossorigin 屬性后,瀏覽器會啟用 CORS(跨域資源共享)檢查。如果服務器沒有正確配置 CORS 響應頭,瀏覽器會拒絕執(zhí)行腳本。
<scriptsrc="https://fly63.com/script.js"crossorigin="anonymous"></script>crossorigin 有兩個可選值:
- anonymous:啟用 CORS 但不發(fā)送憑據(jù)
- use-credentials:啟用 CORS 并發(fā)送憑據(jù)(如 cookies)
使用 crossorigin 的主要好處是:
- 配合 integrity 屬性可以驗證資源完整性,防止腳本被篡改
- 能夠獲取更詳細的腳本錯誤信息
- 符合內容安全策略(CSP)的要求
模塊化腳本:type="module"
現(xiàn)代瀏覽器已經(jīng)支持 ES 模塊,只需設置 type="module" 即可使用 import 和 export 語法。
<scripttype="module">
import { utils } from'./utils.js';
// 使用導入的模塊
</script>使用模塊化腳本有幾個特點:
- 自動啟用嚴格模式
- 支持頂級 await
- 默認具有 defer 的行為(異步加載不阻塞頁面)
- 支持按需導入
對于需要導入映射的情況,可以使用 importmap:
<scripttype="importmap">
{
"imports": {
"vue": "https://unpkg.com/vue@3/dist/vue.esm-browser.js"
}
}
</script>這樣在代碼中就可以直接使用 import Vue from 'vue',而不需要寫完整的 URL。
安全增強:nonce 屬性
除了上述屬性,nonce 也是一個重要的安全特性。它通常與內容安全策略(CSP)一起使用,防止跨站腳本攻擊(XSS)。
nonce 是一個隨機生成的字符串,只有匹配 CSP 頭中指定的 nonce 值的腳本才會被執(zhí)行。
服務器端設置 CSP 頭:
Content-Security-Policy: script-src 'nonce-abc123'HTML 中使用:
<scriptnonce="abc123">
// 只有 nonce 值匹配的腳本才會執(zhí)行
</script>這種方式可以有效防止惡意腳本注入,提高網(wǎng)站安全性。
實際應用建議
- 對于主要功能腳本,優(yōu)先使用 defer 而不是將腳本放在 body 底部
- 加載第三方資源時,總是使用 crossorigin 屬性
- 在現(xiàn)代項目中,可以考慮使用 type="module" 利用瀏覽器原生模塊支持
- 對于重要網(wǎng)站,實施 CSP 策略并使用 nonce 增強安全性
理解這些屬性和它們的用途,不僅能優(yōu)化頁面加載性能,還能提高網(wǎng)站的安全性。雖然有些細節(jié)看起來復雜,但掌握它們對于前端開發(fā)者來說是非常有價值的。
























