FileReader读取图片预览需用readAsDataURL()转base64并赋值img.src,且必须在onload回调中获取reader.result;上传前须校验file.type和file.size,FormData上传时append的必须是File对象而非base64字符串。

FileReader读取文件后怎么显示图片预览
直接用 readAsDataURL() 把 File 对象转成 base64 字符串,再赋给 的 src 属性即可。注意必须等 onload 触发后再取 result,否则是空值。
-
FileReader是异步的,readAsDataURL()调用后立刻返回,内容在onload里才可用 - 别在
onload外访问reader.result,它此时还是null - 预览图尺寸建议用 CSS 控制(如
max-width: 100%),避免大图撑破容器
const reader = new FileReader();
reader.onload = function() {
const img = document.getElementById('preview');
img.src = reader.result; // 这里才是有效的 data URL
};
reader.readAsDataURL(file); // file 来自 input[type="file"].files[0]上传前如何校验文件类型和大小
不能只靠 accept 属性——它只是提示,用户可绕过。必须在 JS 里用 file.type 和 file.size 做实际校验。
-
file.type可能为空(比如拖拽 txt 文件),优先用文件扩展名或file.name.split('.').pop()辅助判断 -
file.size单位是字节,1MB = 1048576 字节,别写成 1000000 - 校验失败要调用
event.preventDefault()阻止后续逻辑,并给出明确提示
if (file.size > 2 * 1048576) {
alert('文件不能超过 2MB');
return;
}
if (!file.type.startsWith('image/')) {
alert('仅支持图片文件');
return;
}用 FormData 上传时为什么后端收不到文件
常见原因是没给 FormData.append() 的第二个参数传入 File 对象本身,而是传了字符串、reader.result 或其他无效值。
-
FormData.append('file', file)才正确;传reader.result是传 base64 字符串,后端收到的是文本字段,不是文件流 - 如果需要额外字段(如描述),用
FormData.append('desc', 'xxx')即可,和文件一起发 -
fetch发送时不要手动设Content-Type,让浏览器自动设置带 boundary 的 multipart/form-data
const formData = new FormData();
formData.append('file', file); // ← 必须是 file 对象
formData.append('name', 'avatar');
fetch('/upload', {
method: 'POST',
body: formData // 不要加 headers: { 'Content-Type': ... }
});
预览+上传流程中容易漏掉的兼容性细节
IE10+ 支持 FileReader,但 IE 不支持 URL.createObjectURL()(虽然这里不用它)。真正要注意的是移动端 Safari 对大图 readAsDataURL() 的内存限制——超 10MB 容易卡死或中断。
立即学习“前端免费学习笔记(深入)”;
- 大文件建议改用
URL.createObjectURL(file)做预览(更快、不占内存),上传仍用原File对象 -
createObjectURL创建的 URL 必须在不用时调用URL.revokeObjectURL()释放引用,否则内存泄漏 - 部分安卓 WebView 对
FileReader的onerror不触发,建议加onabort和超时兜底
预览环节能省则省 base64,上传环节别把预览逻辑和上传逻辑耦合太死——它们本就该是两个独立动作。











