使用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类型没有被所有浏览器完全内置,浏览器无法从文件头或扩展名直接识别,就会返回空字符串。
解决办法
通过文件扩展名推断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); });简化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
相关产品推荐
相关产品推荐

