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

JavaScript如何完整复制File对象保留全部属性仅修改文件名

为上传图片生成带后缀预览图时保留原文件全部属性的方案

需求说明

  • 为待上传的图片生成体积更小的预览图
  • 预览图文件名需要在原文件名末尾追加_preview后缀

原有实现代码

uploadFile.map((file) => {
      if (file.type.includes('image')) {
        console.log('Generating thumbnail for ' + file.name)
        const fileName = file.name.split('.').slice(0, -1).join('.')
        const fileExtension = file.name.split('.').pop()
        const compressedFile = new File(
          [file.slice(0, file.size, file.type)],
          fileName + '_preview.' + fileExtension,
        )
        console.log('Generated file:', compressedFile)
        convert({
          file: compressedFile,
          width: 300,
          height: 300,
          type: fileExtension,
        })
          .then((resp) => {
            uploadFile.push(resp)
          })
          .catch((error) => {
            // Error
            console.error('Error compressing ', file.name, '-', error)
          })
      }
    })

问题原因

创建File实例时没有传入第三个配置参数,导致原文件的MIME类型(type字段)丢失;webkitRelativePath属于File实例的只读属性,不会自动从原文件继承,最终触发convert函数的File type not supported报错。

修复方法

  • 创建新File实例时,显式传入第三个配置对象,把原文件的type、lastModified等可配置属性带上
  • 对于webkitRelativePath这类构造函数不支持直接传入的只读属性,创建实例后通过Object.defineProperty手动赋值

修复后的核心代码

uploadFile.map((file) => {
  if (file.type.includes('image')) {
    console.log('Generating thumbnail for ' + file.name)
    const fileName = file.name.split('.').slice(0, -1).join('.')
    const fileExtension = file.name.split('.').pop()
    // 创建新File时传入配置保留基础属性
    const compressedFile = new File(
      [file],
      `${fileName}_preview.${fileExtension}`,
      {
        type: file.type,
        lastModified: file.lastModified
      }
    )
    // 手动补充webkitRelativePath只读属性
    if (file.webkitRelativePath) {
      Object.defineProperty(compressedFile, 'webkitRelativePath', {
        value: file.webkitRelativePath,
        writable: false,
        configurable: true
      })
    }
    console.log('Generated file:', compressedFile)
    convert({
      file: compressedFile,
      width: 300,
      height: 300,
      type: fileExtension,
    })
      .then((resp) => {
        uploadFile.push(resp)
      })
      .catch((error) => {
        console.error('Error compressing ', file.name, '-', error)
      })
  }
})

注:原代码中file.slice(0, file.size, file.type)属于冗余操作,File本身是Blob的子类,可以直接作为内容参数传入新的File构造函数。

内容的提问来源于stack exchange,提问作者Ashar

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 21:54:52