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

使用useForm上传RAR/ZIP文件时file.type为空的问题排查

React Hook Form上传ZIP/RAR文件时File对象type字段为空的问题

我在使用React Hook Form的useForm组件处理表单上传时遇到一个问题:上传图片文件时,fileList里的文件对象type字段能正常显示MIME类型,但上传RAR或ZIP文件时,这个字段是空字符串。不确定是不是我的代码导致的问题,相关代码片段如下:

<Controller
  name="files"
  control={control}
  render={(fields) => (
    <Button variant="text" component="label">
      Select Files
      <input
        {...fields}
        {...register("files")}
        hidden
        multiple
        type="file"
        accept=".zip,.rar"
      />
    </Button>
  )}
  rules={{ required: true }}
/>
{errors.files && (
  <Typography marginTop={1} color="red" role="alert">
    {errors.files?.message}
  </Typography>
)}
</Grid>
</Grid>
</form>

<Box sx={{ display: "flex", justifyContent: "flex-end" }}>
  <Button
    disabled={days + hours + minutes + seconds <= 0}
    onClick={() => {
      const values = getValues();
      Array.from(values.files).forEach((file) => {
        console.log("🚀 ~ file: view.js:151 ~ Array.from ~ file", file);
      });
    }}
    form="challenge-form"
    variant="contained"
    type="submit"
    sx={{ mt: 3, ml: 1 }}
  >
    {" "}
    Upload
  </Button>

打印的文件对象日志


问题原因

这不是你的代码问题,是浏览器的MIME类型识别机制导致的:

  • 图片类文件(如JPG、PNG)的MIME类型属于浏览器普遍内置的识别列表,所以能正确返回type值;
  • RAR和部分ZIP文件的MIME类型没有被所有浏览器完全内置,浏览器无法从文件头或扩展名直接识别,就会返回空字符串。

解决办法

  1. 通过文件扩展名推断MIME类型
    可以根据文件名的扩展名手动映射对应的MIME类型,弥补浏览器识别的不足:

    const getMimeTypeByExtension = (filename) => {
      const ext = filename.split('.').pop().toLowerCase();
      const mimeMap = {
        zip: 'application/zip',
        rar: 'application/vnd.rar'
      };
      return mimeMap[ext] || '';
    };
    
    // 在获取文件时使用
    Array.from(values.files).forEach((file) => {
      const fileType = file.type || getMimeTypeByExtension(file.name);
      console.log('文件类型:', fileType);
    });
    
  2. 简化React Hook Form的文件注册逻辑
    你的代码同时使用了Controller的fields和register,存在冗余,建议简化:

    <Controller
      name="files"
      control={control}
      render={({ field }) => (
        <Button variant="text" component="label">
          Select Files
          <input
            {...field}
            hidden
            multiple
            type="file"
            accept=".zip,.rar"
          />
        </Button>
      )}
      rules={{ required: true }}
    />
    

    Controller提供的field已经包含了register所需的所有属性,重复使用可能引发不必要的冲突。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 00:41:13