Google存储区signedUploadUrl,获取上载网址返回:错误的内容类型。请使用多部分

问题描述 投票:1回答:3

我想让我的用户直接将大文件上传到Google存储空间。根据this documentation,我应该能够使用PHP SDK生成签名的上传网址。我是这样的:

$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,然后才能获取可以上传到的ACTUAL网址。文档:

signedUploadUrl

为此对象创建一个签名的上载URL。

...

为了上传数据,必须通过发送 从此方法返回的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.

php google-cloud-platform google-cloud-storage php-7 google-cloud-php-client
3个回答
0
投票

似乎您要发布的端点不接受表单多部分数据。尝试将Content-Type设置为“ multipart / related”,而不是“ multipart / form-data”,然后查看是否可以继续。检查此链接Cloud Storage Upload以获取更多帮助。


0
投票

如果邀请用户通过HTML表单上传文件,则需要使用Bucket::generatedSignedPostPolicyV4

该方法将返回一个数组,该数组包含一个动作URI(用于Bucket::generatedSignedPostPolicyV4属性)以及需要包含在表单中的字段列表。对这些对象进行迭代,并使用隐藏的输入将它们作为键/值字段嵌入。

上面链接上的样本格式似乎有些混乱,但是您可以在<form action>中看到完整的样本(如果已简化)。


0
投票

我最初尝试了google提供的示例代码,但没有用(这是两步的signatureUrl()方法,只需要一个api调用和一个PUT调用),所以我经历了多次迭代,尝试了不同的功能和不同的方法(遵循网络上的不同示例),所有这些示例都一直失败(包括三步的signedUploadUrl()方法,该方法需要api调用,POST,然后是另一个POST(或可能是PUT))。

我仍然需要弄清楚如何使它在我的应用程序中正常工作,但是至少我可以使它与curl一起使用,这是对权限和api调用的概念证明。

我最初的curl测试失败的原因是,上传的URL包含标准查询参数,其中包括source code,而当我通过&运行curl命令时,这些参数搞乱了该命令。

因此,使用简单的system()方法返回原始的curl PUT请求,错误的命令如下所示:

signedUrl()

虽然工作命令在URL周围加上了引号,以避免shell抓取和解释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

&
© www.soinside.com 2019 - 2024. All rights reserved.