You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.16 12:01:20