服务端阅读 05月28日 02:35
cURL 如何实现文件上传功能?
cURL 支持多种文件上传方式,核心区别在于 Content-Type 和请求体的组织形式。面试中最高频考察的是 -F 表单上传和 -T PUT 上传的区别。-F 表单上传(multipart/form-data)-F 是最常用的上传方式,模拟浏览器表单提交,自动设置 Content-Type: multipart/form-data:# 基本上传curl -X POST https://api.example.com/upload \ -F "file=@/path/to/document.pdf"# 指定 MIME 类型(服务器可能根据类型做不同处理)curl -X POST https://api.example.com/upload \ -F "file=@/path/to/image.png;type=image/png"# 指定服务器端接收的文件名curl -X POST https://api.example.com/upload \ -F "file=@/path/to/local.txt;filename=uploaded.txt"@ 符号告诉 cURL 读取文件内容而非当作普通字符串。如果误写成 -F "file=/path/to/file",服务器收到的是字面字符串而非文件内容,这是新手最常见的错误。-T PUT 上传(原始文件流)-T 或 --upload-file 将文件作为请求体直接发送,默认使用 HTTP PUT 方法:# HTTP PUT 上传curl -T /path/to/file.pdf https://api.example.com/files/document.pdf# FTP 上传curl -T /path/to/file.zip ftp://ftp.example.com/upload/ \ --user username:password# SFTP 上传curl -T /path/to/file.zip sftp://example.com/upload/ \ --user username:password-T 与 -F 的关键区别:-T 发送的是原始文件流,Content-Type 默认为 application/octet-stream,不会封装成 multipart 格式。RESTful API 中资源更新(如替换已有文件)常用这种方式。多文件上传# 不同字段名上传多个文件curl -X POST https://api.example.com/upload \ -F "avatar=@/path/to/avatar.jpg" \ -F "resume=@/path/to/resume.pdf"# 数组形式上传(后端用 files[] 接收)curl -X POST https://api.example.com/upload \ -F "files[]=@/path/to/file1.pdf" \ -F "files[]=@/path/to/file2.jpg"# 混合文件和普通表单字段curl -X POST https://api.example.com/submit \ -F "name=张三" \ -F "email=zhangsan@example.com" \ -F "avatar=@/path/to/avatar.jpg"二进制上传与 Base64 编码直接发送原始二进制数据,适用于 API 要求 application/octet-stream 的场景:curl -X POST https://api.example.com/upload \ -H "Content-Type: application/octet-stream" \ --data-binary @/path/to/file.bin# 从标准输入读取cat file.bin | curl -X POST https://api.example.com/upload \ -H "Content-Type: application/octet-stream" \ --data-binary @-某些 API 只接受 JSON 请求体,此时需要 Base64 编码:curl -X POST https://api.example.com/upload \ -H "Content-Type: application/json" \ -d "{\"file\":\"$(base64 -w 0 /path/to/file.pdf)\",\"filename\":\"document.pdf\"}"Base64 编码会使数据体积增加约 33%,大文件场景下应优先使用 -F 表单上传。大文件上传与断点续传# 显示上传进度条curl -X POST https://api.example.com/upload \ -F "file=@/path/to/large.zip" \ --progress-bar# 断点续传(需要服务器支持 Range 或 resumable upload)curl -C - -X POST https://api.example.com/upload \ -F "file=@/path/to/large.zip"# 设置超时避免长时间挂起curl --max-time 600 -F "file=@large.zip" \ https://api.example.com/upload-C - 表示自动从上次中断的位置继续传输。注意:真正的断点续传需要服务端支持,对于 multipart 上传,多数服务器并不支持续传,这时需要使用服务端提供的分块上传 API(先获取 uploadId,逐块上传后合并)。带认证的上传# Bearer Token 认证curl -X POST https://api.example.com/upload \ -H "Authorization: Bearer your_token" \ -F "file=@/path/to/file.pdf"# AWS S3 预签名 URL 上传(PUT 方式)curl -X PUT "https://presigned-url-here" \ -H "Content-Type: application/pdf" \ --data-binary @/path/to/file.pdf# 基本认证curl -u username:password -F "file=@file.pdf" \ https://api.example.com/upload关键参数速查| 参数 | 作用 | 适用场景 ||------|------|----------|| -F / --form | multipart 表单上传 | Web 表单、API 文件字段 || -T / --upload-file | PUT 原始文件流上传 | RESTful 资源替换、FTP/SFTP || @ | 读取文件内容 | -F 和 --data-binary 中 || ;type= | 指定 MIME 类型 | -F 中覆盖自动检测 || ;filename= | 指定服务端文件名 | -F 中需要改名的场景 || --data-binary | 发送原始二进制数据 | application/octet-stream || -C - | 断点续传 | 大文件中断后恢复 || --progress-bar | 显示进度条 | 大文件上传监控 |面试常见追问-F 和 -T 上传有什么区别?-F 封装为 multipart/form-data 格式,可以同时传文件和其他字段,适合表单场景。-T 发送原始文件流作为请求体,默认 PUT 方法,适合直接替换资源或 FTP/SFTP 上传。上传文件时 @ 符号的作用是什么?@ 告诉 cURL 读取后面路径的文件内容。不加 @ 时,cURL 会把路径字符串当作普通值发送。如何上传超过服务器限制的大文件?分两种情况:如果是服务器 Content-Length 限制,需服务端调整配置;如果是需要分块上传,要调用服务端提供的 chunked upload API,cURL 本身不自动分块。