向后端 API 上传文件
使用 FormData 和 fetch 以 POST 方式上传文件,并跟踪上传进度。
向后端 API 上传文件 是 CoddyKit 上的免费 React Academy 课时。 这是第 4 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 React Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 React Academy 课程共包含 4 节课。
欢迎
在本课中,您将使用 FormData API 和 fetch 将文件 POST 到后端,使用 XMLHttpRequest 跟踪上传进度,并在 React 中显示上传状态。
FormData API
FormData 是一种浏览器 API,可构建 multipart/form-data 请求正文,这是服务器接收文件上传时所需的格式。请将文件和所有元数据字段追加到 FormData 对象中。
const formData = new FormData();
formData.append('file', selectedFile);
formData.append('description', 'Profile photo');使用 fetch 上传
将 FormData 对象作为 fetch 的请求正文。请勿手动设置 Content-Type——浏览器会自动设置正确的 multipart 边界。
const response = await fetch('/api/upload', {
method: 'POST',
body: formData,
// Do not set Content-Type header here!
});上传状态管理
使用三个状态变量跟踪上传状态:`uploading`(布尔值)、`progress`(0–100)和 `error`(字符串或 null)。根据这些状态显示加载指示器、进度条和错误消息。
const [uploading, setUploading] = useState(false);
const [progress, setProgress] = useState(0);
const [error, setError] = useState(null);使用 XMLHttpRequest 跟踪上传进度
fetch API 不支持上传进度事件。请使用 XMLHttpRequest 的 `upload.onprogress` 事件获取百分比更新。
const xhr = new XMLHttpRequest();
xhr.upload.onprogress = (e) => {
if (e.lengthComputable) {
setProgress(Math.round((e.loaded / e.total) * 100));
}
};
xhr.open('POST', '/api/upload');
xhr.send(formData);将 XHR 包装在 Promise 中
将 XMLHttpRequest 调用包装在 Promise 中,这样您就可以等待其完成,并使用 async/await 处理错误。
function uploadFile(file) {
return new Promise((resolve, reject) => {
const xhr = new XMLHttpRequest();
xhr.onload = () => resolve(xhr.response);
xhr.onerror = () => reject(new Error('Upload failed'));
xhr.upload.onprogress = (e) => setProgress(Math.round(e.loaded / e.total * 100));
xhr.open('POST', '/api/upload');
xhr.send(new FormData().set && (() => { const f = new FormData(); f.append('file', file); xhr.send(f); })());
});
}处理服务器响应
上传成功后解析服务器返回的 JSON 响应。使用返回的 URL 或 ID 更新界面状态。
const res = await fetch('/api/upload', { method: 'POST', body: fd });
if (!res.ok) throw new Error('Upload failed');
const { url } = await res.json();
setUploadedUrl(url);错误处理
始终捕获网络错误和服务器错误。显示便于用户理解的错误消息,并允许用户重试。在 catch 代码块中重置 progress 和 uploading 状态。
try {
setUploading(true);
await uploadToServer(file);
} catch (err) {
setError(err.message);
} finally {
setUploading(false);
}取消上传
将 AbortController 与 fetch 结合使用,以取消正在进行的上传。请将控制器存储在 ref 中,这样就可以从取消按钮调用 abort()。
const abortRef = useRef();
const start = async () => {
abortRef.current = new AbortController();
await fetch('/api/upload', { body: fd, signal: abortRef.current.signal });
};
const cancel = () => abortRef.current?.abort();多文件上传
使用 Promise.all 并行上传多个文件,或使用 for-of 循环按顺序上传。使用以文件名为键的对象跟踪每个文件的单独进度。
快速检查
使用 fetch 和 FormData 时,为什么不应手动设置 Content-Type 标头?
回顾
使用 FormData 构建上传数据。使用 fetch 时不要设置 Content-Type,以便自动生成边界。使用 XMLHttpRequest 的 upload.onprogress 跟踪进度。妥善处理错误,并使用 AbortController 支持取消操作。
课程完成
恭喜您!您已完成 **非受控组件与文件上传**。现在,您可以处理非受控输入、文件选择、拖放以及带进度跟踪的多部分上传。
常见问题解答
「向后端 API 上传文件」课时是免费的吗?
是的 — 「向后端 API 上传文件」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 React Academy 课程的其余内容,请升级到 CoddyKit PRO。 React Academy 课程共包含 4 节课。
「向后端 API 上传文件」这节课中我会学到什么?
使用 FormData 和 fetch 以 POST 方式上传文件,并跟踪上传进度。 你通过在浏览器中直接运行的动手代码来练习 React Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。
学习 React Academy 需要有经验吗?
无需任何先前经验。CoddyKit 上的 React Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 4 节课,共 4 节。
「向后端 API 上传文件」课时需要多长时间?
大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。
我能在这节 React Academy 课中编写并运行代码吗?
能。每节 React Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。
此课程中的所有课时
- 使用 useRef 管理非受控输入
- 文件输入与读取文件数据
- 拖放文件上传界面
- 向后端 API 上传文件