@@ -49,12 +49,14 @@ export const importWorkerScript = () => {
4949
5050 // #IFDEF GECKO
5151 logger . info ( "Register Inject Scripts By Content Script Inline Code" ) ;
52- // 使用 cross.tabs.executeScript 得到的 window 是 content window
53- // 此时就必须要使用 inject script 的方式才能正常注入脚本
54- // 然而这种方式就会受到 content security policy 策略的限制
52+ // 使用 cross.tabs.executeScript 得到的 Window 是 Content Window
53+ // 此时就必须要使用 Inject Script 的方式才能正常注入脚本
54+ // 然而这种方式就会受到 Content Security Policy 策略的限制
5555 // https://github.com/violentmonkey/violentmonkey/issues/1001
56+ // https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/script-src
5657 // https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/webRequest/onHeadersReceived
57- chrome . webRequest . onHeadersReceived . addListener (
58+ // https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/webRequest/onResponseStarted
59+ chrome . webRequest . onResponseStarted . addListener (
5860 res => {
5961 if ( ! res . responseHeaders ) return void 0 ;
6062 if ( res . type !== "main_frame" && res . type !== "sub_frame" ) {
@@ -65,24 +67,14 @@ export const importWorkerScript = () => {
6567 // 仅处理 CSP 的问题
6668 if ( responseHeaderName !== "content-security-policy" ) continue ;
6769 const value = res . responseHeaders [ i ] . value || "" ;
68- const types = value . split ( ";" ) . map ( it => it . trim ( ) ) ;
69- const target : string [ ] = [ ] ;
70- // CSP 不支持多个 nonce, 但可以配置多个 hash
71- // 这里的 hash 会在编译时计算并替换资源
72- // https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/script-src
73- const hashed = "'sha256-${CSP-HASH}'" ;
74- for ( const item of types ) {
75- const [ type , ...rest ] = item . split ( " " ) ;
76- if ( type === "script-src" || type === "default-src" ) {
77- target . push ( [ type , hashed , ...rest ] . join ( " " ) ) ;
78- continue ;
79- }
80- target . push ( item ) ;
81- }
82- // 覆盖原有的响应头, 扩展的 CSP 总是更倾向于更加严格的模式
83- // 实际测试中仅有完全抹除标头时, 才可以解决冲突的问题
84- res . responseHeaders [ i ] . value = target . join ( ";" ) ;
85- // 存在 CSP 时尝试直接在 content script 中执行
70+ // CSP 不支持多个 nonce, 但可以配置多个 sha-hash
71+ // 这里的 hash 会在编译时计算并替换资源 'sha256-${CSP-HASH}'
72+ // 但对 CSP 策略修改存在问题, 这里仅读取并尝试注入, 而不直接增加 hash
73+ // 例如 'self' => ok / 'self'+'hash' => error 宽松到严格结构问题
74+ // 此外即使覆盖原有的响应头, 扩展的 CSP 总是更倾向于更加严格的模式
75+ // 在实际测试中, 仅有完全抹除标头时, 才可以实际解决多个扩展冲突的问题
76+ // ...
77+ // 存在 CSP 时尝试直接在 Content Script 中执行
8678 let code = [
8779 `if (window["${ process . env . INJECT_FILE } "] && document instanceof XMLDocument === false) {` ,
8880 ` window["${ process . env . INJECT_FILE } "]();` ,
@@ -102,7 +94,7 @@ export const importWorkerScript = () => {
10294 code = [
10395 CODE_PREFIX ,
10496 `script.nonce = "${ nonce [ 1 ] } ";` ,
105- `script.innerText = code` ,
97+ `script.innerText = code; ` ,
10698 CODE_SUFFIX ,
10799 ] . join ( "\n" ) ;
108100 }
@@ -125,13 +117,11 @@ export const importWorkerScript = () => {
125117 // @ts -expect-error filter params
126118 cross . tabs . onUpdated . addListener ( onUpdate , { tabId : res . tabId } ) ;
127119 }
128- // 返回修改后的响应头配置
129- return {
130- responseHeaders : res . responseHeaders ,
131- } ;
120+ // onHeadersReceived 仅读取响应头而不修改
121+ return void 0 ;
132122 } ,
133123 { urls : URL_MATCH , types : [ "main_frame" , "sub_frame" ] } ,
134- [ "blocking" , " responseHeaders"]
124+ [ "responseHeaders" ]
135125 ) ;
136126 // #ENDIF
137127} ;
0 commit comments