【发布时间】:2021-03-31 02:50:04
【问题描述】:
我为我的应用上传到 S3 的方法是向我的 PHP 后端发送一个获取请求以生成一个预签名 URL。我知道后端设置正确,因为运行以下命令成功将图像上传到 S3 存储桶:
curl -v -H "Content-Type: image/jpeg" -T ./test.jpeg '<presignedURL>'
但是,我在尝试在 Swift 中上传图片时遇到了问题。这是我目前的实现(请忽略垃圾,硬编码,非错误检查):
后端
<?php
require '../vendor/autoload.php';
use Aws\S3\S3Client;
use Aws\Exception\AwsException;
$response = array();
$client = S3Client::factory(array(
'profile' => 'default',
'version' => 'latest',
'region' => 'us-east-2',
'signature' => 'v4'
));
$command = $client->getCommand('PutObject', array(
'Bucket' => 'test',
'Key' => 'test.jpeg',
'ContentType' => 'image/jpeg',
'Body' => ''
));
$signedUrl = $command->createPresignedUrl('+5 minutes');
$response['error'] = false;
$response['url'] = $signedUrl;
echo json_encode($response);
Swift 代码
import Foundation
import Alamofire
let getTokenURL = "http://192.168.1.59:8000/v1/upload.php"
func submitImage(image: UIImage, completion: @escaping (NSDictionary) -> Void) {
AF.request(getTokenURL, method: .get).responseJSON { response in
switch response.result {
case.success(let value):
let jsonData = value as! NSDictionary
let url = jsonData.value(forKey: "url") as! String
performUpload(image: image, postURL: url)
case.failure(_):
let error_msg: NSDictionary = [
"error" : true,
"message" : "Unknown error occurred. Please try again",
]
//completion(error_msg)
}
}
}
func performUpload(image: UIImage, postURL: String) {
let imageData = image.jpegData(compressionQuality: 0.50)!
AF.upload(imageData, to: postURL, headers: ["Content-Type":"image/jpeg"]) //likely the culprit line
}
当前 URL 从 submitImage() 中的 get 请求返回,并调用 performUpload(),这使得罪魁祸首(可能)成为我 Swift 代码段的最后一个问题。我在阅读文档时无法弄清楚我应该做什么,并且大多数关于这个主题的指南都过时了,因为 AlamoFire 已经改变了它们的语法。任何帮助将不胜感激。谢谢!
编辑: 我已经调整了 performUpload() 函数。它现在将数据上传到 s3 存储桶,但是无法打开图像。我怀疑这是因为请求中的标头不正确。从调试中我可以看出 Content-Type 标头无论如何都是“multipart/form-data”,所以我不确定这种方法是否可行:
struct HTTPBinResponse: Decodable { let url: String }
func performUpload(image: UIImage, postURL: String) {
let imageData = image.jpegData(compressionQuality: 0.50)!
AF.upload(multipartFormData: { multipartFormData in
multipartFormData.append(imageData, withName: "file", mimeType: "image/jpeg")
}, to: postURL, method: .put, headers: ["Content-Type":"image/jpeg"]).responseDecodable(of: HTTPBinResponse.self) { response in
debugPrint(response)
}
}
【问题讨论】:
-
尝试使用multipart form data 请求发送图像数据并查看。
-
@Isuru 请检查我的编辑
-
请求标头为
multipart/form-data没有任何问题。应该是这样的。从标题中删除"Content-Type":"image/jpeg",看看会发生什么。 -
@Isuru 还是同样的问题
-
@Isuru 有点尴尬,但在我原来的解决方案中添加“method: .put”作为参数解决了它
标签: php ios swift amazon-s3 alamofire