网页文件上传核心是用FormData封装文件并通过XMLHttpRequest以multipart/form-data异步提交,不刷新页面、可监听进度、支持错误处理;前端需正确获取文件、设置字段名、自动Content-Type;后端Servlet需@MultipartConfig注解、按约定字段名取Part、处理中文名与CORS;Fetch更简洁但无原生进度监听。

网页文件上传配合 XMLHttpRequest 异步发送到后端,核心是用 FormData 封装文件,并通过 XMLHttpRequest 以 multipart/form-data 方式提交,整个过程不刷新页面、可监听进度、支持错误处理。
前端:构造 FormData 并发起异步请求
关键点在于正确获取文件、封装进 FormData、设置请求方式和监听响应状态:
- 用
<input type="file">获取用户选中的文件(注意files[0]是 File 对象) - 创建
new FormData()实例,调用.append('fieldName', file)添加文件(字段名需与后端约定一致,如uploaded_file) - 创建
XMLHttpRequest实例,.open('POST', '/upload', true)初始化异步请求 - 无需手动设置
Content-Type头——浏览器会自动设为multipart/form-data并带上 boundary - 用
xhr.upload.onprogress监听上传进度,xhr.onload或onreadystatechange处理成功响应
后端:Servlet 接收并解析 Part(Java 示例)
Servlet 需启用文件上传支持(如 Tomcat 8.5+ 默认支持),并使用 request.getPart() 提取文件:
- 确保 Servlet 类添加
@MultipartConfig注解或在web.xml中配置<multipart-config></multipart-config> - 调用
request.getPart("uploaded_file")获取Part对象(字段名必须与前端FormData.append()一致) - 从
Part中读取文件名:part.getSubmittedFileName();读取输入流:part.getInputStream() - 保存文件到服务器路径(注意权限、路径校验、重命名防覆盖),再用
response.getWriter().write(json)返回标准 JSON 响应(如{"success":true,"url":"/uploads/xxx.jpg"})
常见问题与避坑提示
实际开发中容易卡在这几个地方:
- 前端未检查
files.length > 0就取files[0],导致上传空值或报错 - 后端字段名写错(比如前端 append
'file',后端却 getPart'uploaded_file'),结果取不到 Part - 未处理中文文件名:浏览器可能用 UTF-8 编码提交,
getSubmittedFileName()在某些容器中返回乱码,建议统一转 UTF-8 或用正则提取原始文件名 - 忽略 CORS:若前后端域名不同,后端需加
Access-Control-Allow-Origin响应头(含 credentials 时不能设为*) - 大文件上传超时:需同步调整 Servlet 容器的上传限制(如 Tomcat 的
maxFileSize和maxRequestSize)
替代方案:Fetch API 更简洁(可选)
如果项目环境支持现代浏览器,Fetch 是更推荐的替代方式:
- 语法更清晰:
fetch('/upload', { method: 'POST', body: formData }) - 天然支持 Promise,配合
async/await更易读写 - 但原生 Fetch 不支持上传进度监听(需借助
ReadableStream或第三方库如uploadx) - 仍需后端按相同逻辑接收
multipart/form-data,兼容性无差别
















