Swift通过可恢复API上传视频到Vimeo第二步报Content-Type错误如何解决
问题根因
你的请求报错核心原因是错误使用了Alamofire的multipart表单上传接口,直接违反了Vimeo可恢复上传的tus协议规范:
- tus协议要求第二步PATCH请求的请求体是纯二进制视频流,对应Content-Type必须为你手动设置的
application/offset+octet-stream。但调用AF.upload(multipartFormData:)方法时,Alamofire会自动将Content-Type重写为multipart/form-data; boundary=随机边界值,直接覆盖你手动配置的头字段,服务端收到请求后校验Content-Type不匹配,就会返回对应错误。 - 你当前的实现还有两个额外隐患:
- multipart场景下的
withName参数是用来指定表单字段名的,纯二进制流上传不需要这个配置,强行加会在二进制流前后插入表单分隔符,导致服务端解析视频内容失败。 - 用
Data(contentsOf:)把整个视频文件全量加载进内存,上传大体积视频时会触发内存暴涨,很容易被系统直接杀死进程。
- multipart场景下的
修复代码
直接使用Alamofire的文件上传接口,不要走multipart逻辑,传入本地视频URL即可,Alamofire不会篡改你预设的请求头,同时会以分片读文件的方式上传,避免内存溢出:
private func uploadVideoToVimeo(uploadLink:String) { guard let uploadUrl = URL(string: uploadLink) else { return } let headers: HTTPHeaders = [ "Tus-Resumable":"1.0.0", "Upload-Offset": "0", "Content-Type": "application/offset+octet-stream", "Accept":"application/vnd.vimeo.*+json;version=3.4" ] var request = URLRequest(url: uploadUrl) request.headers = headers request.method = .patch // 直接传入本地文件URL上传,不要构造multipart表单 AF.upload(self.videoLocalURL, with: request) .responseString { response in switch response.result { case .success(let data): print("上传响应: \(response)") // 后续断点续传可从响应头的Upload-Offset字段获取当前上传进度 case let .failure(error): print("上传错误: \(error)") } } }
后续注意事项
- 实现完整可恢复上传逻辑时,不要硬编码
Upload-Offset为0,每次发起续传请求前需要先向上传地址发送HEAD请求,获取服务端实际存储的文件偏移量,再从对应位置开始上传剩余内容,避免出现内容覆盖、上传损坏的问题。 - 如果需要监听上传进度,可以给上传请求追加
uploadProgress回调,不要手动计算分片大小,Alamofire底层会自动处理流读取逻辑。
内容的提问来源于stack exchange,提问作者anchor
相关产品推荐
相关产品推荐

