【发布时间】:2020-06-10 05:56:57
【问题描述】:
我想让我的用户将大文件直接上传到 Google 存储。根据this documentation,我应该能够使用 PHP SDK 生成签名的上传 url。我是这样做的:
$storage = new StorageClient(['keyFilePath' => $myKeyPath ]);
$bucket = $storage->bucket($bucketname);
$object = $bucket->object($relativepath);
$sessionURI = $object->signedUploadUrl(
# This URL is valid for 15 minutes
new \DateTime('15 min'),
[
'method' => 'PUT',
'contentType' => 'application/octet-stream',
'version' => 'v4',
]
);
文档说我需要POST 到返回的$sessionURI 才能获得我可以上传到的实际网址。文档:
签名上传网址
为此对象创建签名上传 URL。
...
为了上传数据,必须通过发送一个会话 URI 对此方法返回的 URL 的 HTTP POST 请求。
但是,当我尝试将POST 转至$sessionURI 时,我收到错误消息:
POST object expects Content-Type multipart/form-data
所以,我明确地将Content-Type 设置为multipart/form-data,然后我得到了错误:
Bad content type. Please use multipart.
我尝试从代码中执行此操作以及在命令行上使用 curl,我尝试设置 Content-Type 但似乎没有任何效果(我添加了一些新行以使其可读,但仅此而已原来一行):
/usr/bin/curl -X POST -H "Content-Type: multipart/form-data"
https://storage.googleapis.com/my-project-id.appspot.com/uploads/uploadfilename.jpg?GoogleAccessId=myserviceaccount
@mydomain.com&Expires=1591657512&Signature=veryverylongsignatureasdfasdfasdfasdfadfa
sdfasdfasdfasdfasdfasdfasdfasdfasdfadsfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfa
sdfasdfasdfasdfasdfasdfasdfasdfasdf
我尝试了许多不同的示例,并且尝试完全按照文档中的说明进行操作,但似乎没有任何效果。
我错过了什么?我究竟做错了什么?
---- 更新
我尝试使用 Google 的示例代码回到开头,但仍然无法正常工作。这是 Google 的示例代码给我的 curl 命令:
curl -X PUT -H 'Content-Type: application/octet-stream' --upload-file /path/to/file.jpg
https://storage.googleapis.com/my-project-id.appspot.com/uploads/uploadfilename.jpg?GoogleAccessId=myserviceaccount
@mydomain.com&Expires=1591657512&Signature=veryverylongsignatureasdfasdfasdfasdfadfa
sdfasdfasdfasdfasdfasdfasdfasdfasdfadsfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfa
sdfasdfasdfasdfasdfasdfasdfasdfasdf
那是给我的:
Anonymous caller does not have storage.objects.create access to the Google Cloud Storage object.
【问题讨论】:
-
您似乎正在尝试开始可恢复上传。开始可恢复上传的请求是 POST 请求。您的 PHP 代码正在签署执行 PUT 请求的请求。
-
您必须使用登录实际请求时指定的相同 HTTP 方法。在您的情况下,您应该使用 PUT 方法。对于
curl,使用-T选项。您提到“大文件”。任何大于几百兆字节的数据都可能导致糟糕的用户体验。 -
@JohnHanley PUT 是最终的上传请求应该是什么,但我仍处于尝试获取我可以 PUT 的 uri 的中间步骤,并且该请求需要根据文档发布 POST 。此上传将在 iOS 应用的后台进行,用户体验会很好。
-
@BrandonYarbrough PUT 是最终的上传请求应该是什么,但我仍处于尝试获取我可以 PUT 的 uri 的中间步骤,并且该请求需要根据文档发布 POST。
-
我评论的重点是签名中指定的方法必须与请求方法匹配。接下来,你要文件上传还是
resumable文件上传?在第一种情况下使用 PUT,在第二种情况下使用 POST。curl支持第一种方法。上传Tpe参考此链接:cloud.google.com/storage/docs/json_api/v1/objects/insert
标签: php google-cloud-platform google-cloud-storage php-7 google-cloud-php-client