如何使用React检测文件扩展名 判断图片/PDF时仅else分支生效
代码问题排查
原代码无法识别PDF的核心原因有3个:
- 属性取值错误:浏览器原生File对象的类型属性为
type,不存在名为.type的属性,selectedFile['.type']取值永远为undefined,判断条件始终不成立 - 判断值错误:
type属性存储的是文件MIME类型,PDF对应的MIME值为application/pdf,并非字符串.pdf,就算取对属性也无法匹配 - 逻辑缺失:没有做非图片、非PDF格式的兜底处理,遇到其他格式文件会默认按图片渲染导致异常
React环境正确实现方案
优先推荐使用MIME类型做判断,可靠性远高于后缀名校验(可避免用户手动修改文件后缀导致的识别错误),完整实现代码如下:
const thumbs = files.map((selectedFile) => { const fileMime = selectedFile.type; // 判断是否为PDF const isPdf = fileMime === "application/pdf"; // 匹配常见图片格式 const isImage = [ "image/png", "image/jpeg", "image/gif", "image/webp", "image/bmp", "image/svg+xml" ].includes(fileMime); return ( <div key={selectedFile.name} className="d-flex"> {isPdf ? ( <iframe src={selectedFile.preview} style={{ height: "20%", width: "20%" }} title={selectedFile.name} /> ) : isImage ? ( <img src={selectedFile.preview} alt={selectedFile.name} style={{ height: "20%", width: "20%" }} /> ) : ( <div className="unsupported-tip">当前文件格式暂不支持预览</div> )} </div> ); });
后缀名校验兜底方案
如果遇到特殊场景无法获取正确MIME值,可通过提取文件后缀名做判断,注意该方案可靠性更低,仅作为兜底使用:
// 提取文件后缀的工具方法,自动处理无后缀、多后缀等边界情况 const getFileExt = (fileName) => { return fileName.slice(((fileName.lastIndexOf(".") - 1) >>> 0) + 2).toLowerCase(); }; // 业务代码中使用 const thumbs = files.map((selectedFile) => { const fileExt = getFileExt(selectedFile.name); const isPdf = fileExt === "pdf"; const isImage = ["png", "jpg", "jpeg", "gif", "webp", "bmp", "svg"].includes(fileExt); // 渲染逻辑和上述MIME判断方案一致 })
实现注意事项
iframe标签必须添加title属性,符合React无障碍规范,避免控制台抛出警告- 判断相等时统一使用
===严格相等,避免==隐式类型转换带来的边界问题 - 必须添加不支持格式的兜底逻辑,避免异常文件导致页面渲染报错
内容的提问来源于stack exchange,提问作者Milindi Senevirathne
相关产品推荐
相关产品推荐

