跳转到主内容
趣航编程网 - 趣学编程,启航技术之路!

index.html如何制作带有进度条的表单提交?

最可靠方式是用 XMLHttpRequest 手动提交并监听 upload.onprogress,因 fetch 尚不支持上传进度;需阻止表单默认提交、用 FormData 收集数据、不手动设 Content-Type、校验 lengthComputable 防 NaN、上传完成设 progress.value=100。 用
XMLHttpRequest
监听上传进度最可靠 浏览器原生 表单提交 (
submit
)不暴露上传过程,没法做进度条。必须改用
XMLHttpRequest
或
fetch
手动发请求,才能监听
upload.onprogress
。现代项目推荐用
XMLHttpRequest
,因为
fetch
目前仍不支持上传进度事件(
UploadProgress
是草案,Chrome/Firefox 都没实现)。 常见错误是直接对
form.submit()
绑定
onprogress
——这完全无效,事件根本不会触发。 先
event.preventDefault()
阻止默认提交 用
new FormData(form)
收集字段(支持文件、文本、多选等) 创建
XMLHttpRequest
,监听
upload.onprogress
更新
元素的
value
注意:
onprogress
只在上传阶段触发,不是整个请求生命周期
FormData
传文件时要避免手动设
Content-Type
如果用
XMLHttpRequest
发送
FormData
,千万别手动设置
Content-Type
头。浏览器会自动加上带随机 boundary 的
multipart/form-data
,手动覆盖会导致后端收不到文件(PHP 的
$_FILES
为空,Node.js 的
multer
报错
Unexpected end of form
)。 正确写法是让浏览器自动生成头: 立即学习 “ 前端免费学习笔记(深入) ”; 使用HTML,CSS,JavaScript开发Android应用程序 英文文字pdf版附源文件 如果你了解HTML,CSS和JavaScript,您已经拥有所需的工具开发Android应用程序。本动手本书展示了如何使用这些开源web标准设计和建造,可适应任何Android设备的应用程序 - 无需使用Java。您将学习如何创建一个在您选择的平台的Andr​​oid友好的网络应用程序,然后转换与自由PhoneGap框架到一个原生的Andr​​oid应用程序。了解为什么设备无关的移动应用是未来的潮流,并开始构建应用程序,提供更 下载
xhr.open('POST', '/upload'); // ❌ 错误:xhr.setRequestHeader('Content-Type', 'multipart/form-data'); // ✅ 正确:什么都不设,让浏览器处理 xhr.send(formData);
如果需要额外参数(如 token),用
formData.append('token', 'xxx')
追加,别塞进 headers 纯 JSON 提交不用进度条,但若混传文件 + JSON 字段,必须用
FormData
,不能
JSON.stringify
元素更新要防 NaN 和重复触发
event.loaded
和
event.total
在小文件或本地测试时可能为 0,直接除会导致
NaN
,
会卡死或显示异常。同时,某些浏览器(如 Safari)会在上传结束前多次触发
onprogress
,但
loaded === total
不一定只出现一次。 更新前加判断:
if (e.lengthComputable) { progress.value = (e.loaded / e.total) * 100; }
把
写死,不要依赖 JS 设置
max
提交按钮建议在开始上传时
disabled
,防止用户连点;成功/失败后再恢复 上传完成(
xhr.onload
)后记得手动设
progress.value = 100
,避免因四舍五入差 0.1% 卡在 99% 服务端返回 200 但前端报错?检查响应体格式 进度条能动,但最终
xhr.onload
拿不到数据,或者解析 JSON 失败,大概率是服务端返回了非 JSON 内容(比如 PHP 输出了 warning、Node.js 忘了
res.end()
、Nginx 加了额外 header)。此时
xhr.response
可能是 HTML 或空字符串,
JSON.parse
就会抛错。 用浏览器 DevTools 的 Network 面板看「Response」标签页,确认返回的是纯 JSON(如
{"ok":true}
) 后端务必关掉调试输出(PHP 的
error_reporting(0)
,Python 的
logging
关闭) 前端加兜底:
try { JSON.parse(xhr.response); } catch(e) { console.error('Invalid JSON:', xhr.response); }
进度条本身不解决后端逻辑问题,但它把“卡住”变成了可观察的数值——这恰恰是最容易被忽略的:你看到进度走到 100%,不代表后端已处理完,只代表字节发完了。

相关文章