存在多次重定向时,img元素的onLoad事件监听器何时触发?
图片加载的load事件在重定向场景下的触发时机及测试方法
触发时机
load事件只会在整个重定向链走完,最终的有效图片资源成功加载完成后才会触发,不会在中间的重定向请求阶段触发。
浏览器处理图片请求时,会自动跟随所有重定向(301/302等状态码),直到获取到返回200状态码的真实图片资源。只有当图片资源完成下载、解码并准备好渲染时,才会触发load事件。中间的重定向只是请求跳转,并没有实际加载图片内容,因此不会触发该事件。
另外注意:你的示例代码缺少设置img.src的关键步骤,这是触发图片请求的必要操作,修正后的代码如下:
return new Promise(resolve => { let img = new Image(); img.addEventListener('load', () => resolve()); img.src = '存在重定向链的图片URL'; // 必须设置src才会发起请求 });
测试方法
方法一:本地服务器模拟重定向链
- 搭建简单本地HTTP服务器,比如用Node.js实现:
创建一个server.js文件,内容如下:const http = require('http'); const fs = require('fs'); const path = require('path'); const server = http.createServer((req, res) => { if (req.url === '/redirect1') { console.log('收到重定向1请求'); res.writeHead(302, { Location: '/redirect2' }); res.end(); } else if (req.url === '/redirect2') { console.log('收到重定向2请求'); res.writeHead(302, { Location: '/test.jpg' }); res.end(); } else if (req.url === '/test.jpg') { console.log('收到真实图片请求'); const imgPath = path.join(__dirname, 'test.jpg'); fs.readFile(imgPath, (err, data) => { if (err) { res.writeHead(404); res.end('图片不存在'); } else { res.writeHead(200, { 'Content-Type': 'image/jpeg' }); res.end(data); } }); } }); server.listen(3000, () => { console.log('服务器运行在http://localhost:3000'); }); - 准备一张名为
test.jpg的图片放在同一目录,启动服务器:node server.js - 运行你的图片加载代码,将
img.src设为http://localhost:3000/redirect1,同时在load回调中添加console.log('图片load事件触发') - 观察服务器控制台的请求日志和浏览器控制台的日志,会看到先依次打印重定向请求日志,最后才打印
图片load事件触发
方法二:浏览器开发者工具追踪
- 找到一个存在重定向链的图片URL(或用上面的本地服务器)
- 打开浏览器开发者工具(F12),切换到「网络」面板,勾选「保留日志」选项
- 运行图片加载代码,观察网络请求列表:会看到多个标注为「302 Found」的重定向请求,最后一个是状态码200的图片请求
- 查看浏览器控制台的日志,
load事件的日志会在最后一个200请求完成后出现,以此验证触发时机
内容的提问来源于stack exchange,提问作者Niko
相关产品推荐
相关产品推荐

