Chrome扩展上下文无法自动携带低熵Client-Hints问题排查
Chrome扩展上下文无法自动携带低熵Client Hints的解决方案
问题背景
我正在开发Chrome扩展,需要收集点击事件并发送到后端xyz.com,希望为请求添加低熵Client Hints头部(Sec-CH-UA、Sec-CH-UA-Mobile、Sec-CH-UA-Platform)来丰富数据。已知高熵提示需要第一方网页携带Delegate头部,但预期扩展上下文会自动携带低熵提示,实际却没有实现,也没找到相关禁止规则。
请求头对比
--------------------------- # 网页上下文请求 # --------------------------- ----- 请求行 ----- GET / HTTP/1.1. ----- 请求头 ----- Host: localhost:8000 Connection: keep-alive Pragma: no-cache Cache-Control: no-cache sec-ch-ua-full-version-list: "Not A(Brand";v="8.0.0.0", "Chromium";v="132.0.6834.84", "Google Chrome";v="132.0.6834.84" Custom-Header-1: from page context Custom-Header-2: Value2 sec-ch-ua-platform: "macOS" Accept-Language: en-GB,en;q=0.9 sec-ch-ua: "Not A(Brand";v="8", "Chromium";v="132", "Google Chrome";v="132" sec-ch-ua-model: "" sec-ch-ua-mobile: ?0 sec-ch-ua-full-version: "132.0.6834.84" User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/132.0.0.0 Safari/537.36 sec-ch-ua-platform-version: "15.2.0" Accept: */* Sec-Fetch-Site: same-origin Sec-Fetch-Mode: cors Sec-Fetch-Dest: empty Referer: http://localhost:8000/ Accept-Encoding: gzip, deflate, br, zstd -------------------- ----------------------------- # 扩展上下文请求 # ----------------------------- ----- 请求行 ----- GET / HTTP/1.1 ----- 请求头 ----- Host: localhost:8000 Connection: keep-alive Pragma: no-cache Cache-Control: no-cache User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/132.0.0.0 Safari/537.36 Custom-Header-1: from extension context Fetch API Custom-Header-2: Value2 Accept: */* Sec-Fetch-Site: none Sec-Fetch-Mode: cors Sec-Fetch-Dest: empty Accept-Encoding: gzip, deflate, br, zstd Accept-Language: en-GB,en-US;q=0.9,en;q=0.8 --------------------
核心原因
- 扩展上下文是独立的隔离环境,Chrome不会为扩展发起的请求自动注入低熵Client Hints——网页的Client Hints是基于第一方站点规则自动添加的,而扩展不属于第一方网页范畴。
- 扩展请求带有
Sec-Fetch-Site: none标记,属于无关联上下文的跨站请求,Chrome默认不会为这类请求添加Client Hints头部。
解决方法
1. 手动构造并添加低熵Client Hints头部
利用navigator.userAgentDataAPI获取低熵数据,在Fetch请求中手动注入头部:
// 获取低熵Client Hints数据 const uaData = navigator.userAgentData; const clientHintsHeaders = { 'Sec-CH-UA': uaData.brands.map(brand => `"${brand.brand}";v="${brand.version}"`).join(', '), 'Sec-CH-UA-Mobile': uaData.mobile ? '?1' : '?0', 'Sec-CH-UA-Platform': `"${uaData.platform}"` }; // 发起请求时携带头部 fetch('https://xyz.com/your-event-endpoint', { method: 'POST', // 根据实际需求调整请求方法 headers: { ...clientHintsHeaders, 'Content-Type': 'application/json', // 其他自定义头部 'Custom-Header-1': 'from extension context' }, body: JSON.stringify({ /* 点击事件数据 */ }) });
注意:
navigator.userAgentData在Chrome 90+版本可用,若需兼容旧版本,可从navigator.userAgent中解析相关信息,但准确性会降低。
2. 配置扩展权限与后端CORS
- 在扩展的
manifest.json中声明目标后端的权限,确保扩展有权限向该域名发起请求:{ "manifest_version": 3, // 对应你的扩展版本 "permissions": [ "https://xyz.com/*" ] } - 后端需配置CORS允许这些Client Hints头部,在响应头中添加:
Access-Control-Allow-Headers: Sec-CH-UA, Sec-CH-UA-Mobile, Sec-CH-UA-Platform, Content-Type
3. 区分扩展上下文类型(可选)
如果是内容脚本注入到网页中,也可以考虑通过网页上下文发起请求(比如调用网页的Fetch),此时会自动携带网页的Client Hints,但这种方式会失去扩展的隔离性,且可能受网页CSP限制,需谨慎使用。
内容的提问来源于stack exchange,提问作者Raj-wfx
相关产品推荐
相关产品推荐

