instanceof与constructor.name差异:Safari中Blob类型验证失败排查
Safari中Blob的instanceof判断异常分析与解决方案
背景
我们通过GET接口获取图片,请求配置如下:
Accept: 'application/octet-stream', responseType: 'blob'
并使用以下方法在UI上展示图片:
let imageUrl = URL.createObjectURL(data);
该方案在Chrome(Windows和Mac系统)的几乎所有场景下运行正常,但在Safari的某场景中出现错误:
"Response is not a Blob."
经调试发现,该错误来自Angular的以下代码逻辑:
case 'blob': return res$.pipe(map((res) => { // Validate that the body is a Blob. if (res.body !== null && !(res.body instanceof Blob)) { throw new Error('Response is not a Blob.'); } return res.body; }));
测试显示:
res.body instanceof Blob // Chrome中为true,Safari中为false
在Safari中进一步调试发现:
res.body.constructor.name 返回结果为 "Blob"
问题
如何确定instanceof的输出结果?为什么会出现上述Safari中的异常情况?
解答
1. instanceof的核心判断逻辑
instanceof的本质是检测构造函数的prototype是否存在于实例对象的原型链上。只有满足两个条件时才会返回true:
- 实例对象的原型链能找到目标构造函数的
prototype属性 - 实例和构造函数处于同一个全局执行上下文中
2. Safari异常的根本原因
在Safari的部分特殊场景(如跨iframe通信、Service Worker环境、Angular HTTP拦截器导致的上下文隔离)中,接口返回的res.body对应的Blob构造函数,和当前代码中引用的Blob构造函数来自不同的全局上下文。此时:
- 两者的
prototype不是同一个对象,导致instanceof判断失败 - 但构造函数的
name属性仍会保留为"Blob",所以res.body.constructor.name显示正常
3. 可靠的Blob类型判断方案
如果需要跨浏览器、跨上下文准确判断Blob类型,推荐使用以下几种方法:
Object.prototype.toString(最可靠):Object.prototype.toString.call(res.body) === '[object Blob]'- 检查构造函数名称:
res.body?.constructor?.name === 'Blob' - 验证核心特征:
res.body !== null && typeof res.body.size === 'number' && typeof res.body.slice === 'function'
4. Angular代码的修复示例
将Angular中原有的instanceof判断替换为更可靠的toString方式:
case 'blob': return res$.pipe(map((res) => { // Validate that the body is a Blob. const isBlob = res.body !== null && Object.prototype.toString.call(res.body) === '[object Blob]'; if (!isBlob) { throw new Error('Response is not a Blob.'); } return res.body; }));
内容的提问来源于stack exchange,提问作者Nitish
相关产品推荐
相关产品推荐

