测量HTTP请求TTFB时,S3请求的PerformanceResourceTiming属性异常为0
解决跨源S3资源无法获取PerformanceResourceTiming时序数据的问题
这个问题的核心原因是跨源资源的Performance API访问限制:浏览器出于安全策略,默认会限制页面访问跨源资源的详细时序属性(比如requestStart、responseStart),除非目标服务器返回Timing-Allow-Origin响应头,明确允许当前页面的源获取这些数据。
你遇到的情况中,Cloudflare的资源返回了符合要求的Timing-Allow-Origin头,所以能正常读取时序数据;而S3存储桶的那个0KB PDF请求没有返回该头,导致PerformanceResourceTiming的关键属性未被填充。
下面分两种场景给出解决方案:
场景1:你拥有该S3存储桶的控制权
你需要在S3的CORS配置中添加规则,让存储桶返回Timing-Allow-Origin头:
- 登录AWS控制台,找到目标S3存储桶,进入「权限」标签页
- 编辑「跨源资源共享(CORS)」配置,添加包含
Timing-Allow-Origin的规则,示例配置如下:
<CORSConfiguration> <CORSRule> <!-- 替换为你的页面所在的源,比如https://your-app.com,*代表允许所有源(生产环境不建议) --> <AllowedOrigin>https://your-app.com</AllowedOrigin> <AllowedMethod>GET</AllowedMethod> <AllowedHeader>*</AllowedHeader> <!-- 暴露Timing-Allow-Origin头,同时可以按需添加其他需要访问的响应头 --> <ExposeHeader>Timing-Allow-Origin</ExposeHeader> <ExposeHeader>Content-Length</ExposeHeader> </CORSRule> </CORSConfiguration>
- 保存配置后,重新发起Fetch请求,此时就能正常读取
requestStart和responseStart等属性了。
场景2:你无法控制该S3存储桶
可以通过同源代理的方式绕开跨源限制:在你自己的服务器上搭建一个代理接口,将页面的请求转发到S3资源,同时在代理的响应中添加Timing-Allow-Origin头。
以Node.js + Express为例,简单的代理实现代码如下:
const express = require('express'); const { createProxyMiddleware } = require('http-proxy-middleware'); const app = express(); // 配置代理规则 app.use('/proxy-s3-pdf', createProxyMiddleware({ target: 'https://s3-us-west-2.amazonaws.com/speedtest.waveform.com', changeOrigin: true, pathRewrite: { '^/proxy-s3-pdf': '/ping.pdf' }, onProxyRes: (proxyRes, req, res) => { // 添加Timing-Allow-Origin头,允许你的页面源访问时序数据 res.setHeader('Timing-Allow-Origin', 'https://your-app.com'); } })); app.listen(3000, () => { console.log('Proxy server running on port 3000'); });
之后,页面中的Fetch请求改为调用这个代理接口:
let url = "/proxy-s3-pdf"; await fetch(url).then(res => res.text()); let perf = performance.getEntriesByName(url).pop(); console.log("ttfb", perf.responseStart - perf.requestStart);
因为请求的是同源的代理接口,浏览器会完整返回PerformanceResourceTiming的所有时序属性。
验证方法
你可以在Chrome开发者工具的Network面板中,查看S3请求的响应头:如果没有Timing-Allow-Origin字段,就确认是这个问题导致的;而Cloudflare的请求应该能看到该字段。
内容的提问来源于stack exchange,提问作者Arshan Khanifar
相关产品推荐
相关产品推荐

