Php 亚马逊S3内容类型赢得';执行POST请求时不能设置

Php 亚马逊S3内容类型赢得';执行POST请求时不能设置,php,http,amazon-web-services,amazon-s3,Php,Http,Amazon Web Services,Amazon S3,AccessDenied根据策略无效:额外输入字段:内容类型 当我有这个 ------WebKitFormBoundaryZIsnhgiAKpAVIsBT Content-Disposition: form-data; name="acl" public-read ------WebKitFormBoundaryZIsnhgiAKpAVIsBT Content-Disposition: form-data; name="awsaccesskeyid" my-access-key-id ---

AccessDenied根据策略无效:额外输入字段:内容类型

当我有这个

------WebKitFormBoundaryZIsnhgiAKpAVIsBT
Content-Disposition: form-data; name="acl"

public-read
------WebKitFormBoundaryZIsnhgiAKpAVIsBT
Content-Disposition: form-data; name="awsaccesskeyid"

my-access-key-id
------WebKitFormBoundaryZIsnhgiAKpAVIsBT
Content-Disposition: form-data; name="bucket"

my-bucket
------WebKitFormBoundaryZIsnhgiAKpAVIsBT
Content-Disposition: form-data; name="Content-Type"

image/png
------WebKitFormBoundaryZIsnhgiAKpAVIsBT
Content-Disposition: form-data; name="key"

images/anime_girl.png
------WebKitFormBoundaryZIsnhgiAKpAVIsBT
Content-Disposition: form-data; name="policy"

my-policy
------WebKitFormBoundaryZIsnhgiAKpAVIsBT
Content-Disposition: form-data; name="signature"

my-signature
------WebKitFormBoundaryZIsnhgiAKpAVIsBT
Content-Disposition: form-data; name="success_action_status"

201
------WebKitFormBoundaryZIsnhgiAKpAVIsBT
Content-Disposition: form-data; name="file"; filename="anime_girl.png"
Content-Type: image/png
但是,如果我在下面的代码中完全省略了
内容类型
,则会上载文件,但没有正确的内容类型

        "acl" => "public-read",
        "awsaccesskeyid" => $s3->getAwsAccessKeyId(),
        "bucket" => $s3->getBucket(),
        "Content-Type" => $inputs['type'],
        "key" => "images/" . $inputs['name'],
        "policy" => $s3->getPolicy(true),
        "signature" => $s3->getSignedPolicy(),
        "success_action_status" => "201"
我还尝试将内容类型添加到
策略中
,但出现了此错误


AccessDenied根据策略无效:策略条件失败:[“以开始”、“内容类型”、“图像/png”]

我尝试了一些其他的建议,但得到了这个错误


AccessDenied根据策略无效:策略条件失败:[“eq”、“内容类型”、“图像/png”]

这是我的cors配置

<CORSRule>
    <AllowedOrigin>*</AllowedOrigin>
    <AllowedMethod>PUT</AllowedMethod>
    <AllowedMethod>POST</AllowedMethod>
    <AllowedMethod>DELETE</AllowedMethod>
    <AllowedHeader>*</AllowedHeader>
</CORSRule>

问题在于,在bucket中,文件的内容类型为
二进制/八位字节流
,因此图像不会在浏览器中查看,而是下载(这不是我想要的)。因此,我不确定为什么亚马逊在我的请求负载看起来如上所示时没有适当设置内容类型。

尝试在“prams”级别数组中抵消
ContentType

"acl" => "public-read",
"awsaccesskeyid" => $s3->getAwsAccessKeyId(),
"bucket" => $s3->getBucket(),
"key" => "images/" . $inputs['name'],
"policy" => $s3->getPolicy(true),
"signature" => $s3->getSignedPolicy(),
"success_action_status" => "201",
// indent "ContentType" within a "params" array
"params" => array(
    "ContentType" => $inputs['type']
)

下面是我将文件上载到S3时的一个示例工作请求负载:

------WebKitFormBoundary9Vtjs2zgAF5jJgHC
Content-Disposition: form-data; name="key"

uploads/tmp/dbdfc12f-665e-4389-a739-f345e7acea48/svg_3927.zip
------WebKitFormBoundary9Vtjs2zgAF5jJgHC
Content-Disposition: form-data; name="AWSAccessKeyId"

xxx
------WebKitFormBoundary9Vtjs2zgAF5jJgHC
Content-Disposition: form-data; name="acl"

public-read
------WebKitFormBoundary9Vtjs2zgAF5jJgHC
Content-Disposition: form-data; name="policy"

xxx
------WebKitFormBoundary9Vtjs2zgAF5jJgHC
Content-Disposition: form-data; name="signature"

xxx=
------WebKitFormBoundary9Vtjs2zgAF5jJgHC
Content-Disposition: form-data; name="success_action_status"

201
------WebKitFormBoundary9Vtjs2zgAF5jJgHC
Content-Disposition: form-data; name="file"; filename="svg_3927.zip"
Content-Type: application/zip
正如您所看到的,内容类型仅在末尾与文件数据一起设置一次

更新:

以下是我的开发桶的COR:

    <AllowedOrigin>*</AllowedOrigin>
    <AllowedMethod>GET</AllowedMethod>
    <AllowedMethod>POST</AllowedMethod>
    <AllowedMethod>PUT</AllowedMethod>
    <MaxAgeSeconds>3000</MaxAgeSeconds>
    <AllowedHeader>Authorization</AllowedHeader>
    <AllowedHeader>Content-*</AllowedHeader>
    <AllowedHeader>Host</AllowedHeader>
    <AllowedHeader>*</AllowedHeader>
*
得到
邮递
放
3000
授权
内容-*
主办
*
注意
Content-*
,这可能会解决您的问题

根据,您确实可以将
内容类型
作为表单字段传递,但是

所以你需要这样的东西:

策略:

{
“到期日”:“2007-12-01T12:00:00.000Z”,
“条件”:[
{“acl”:“公共读取”},
{“bucket”:“johnsmith”},
[“以“,“$key”,“user/eric/”开头],
[“以“,”$Content-Type“,”“”开头],
...
]
}
这里的相关行是
[“以“,$Content-Type”开头,“”]
。文档中指出,“match any”类型的条件应该是一个带有空值的“starts with”。如果要将内容类型限制为某种类型,则应使用
[“以“,”$content-type”,“image/”]

表格:

(示例取自S3文档,相应地更改值)


文件的标记:

文件:
正如您在第一个有效负载中所做的那样,您确实为表单设置了一个“内容类型”字段。这一点,加上最新的政策,应该会起作用

不过,作为补充说明,如果您事先知道要上载的文件的类型,则应该将策略和表单字段都设置为该类型。但是,如果您正在上载不同类型的文件,您可以在策略中将内容类型条件设置为“匹配任何”,并且您可以编写一个简单的javascript来拦截表单的
submit
事件,以动态更改
内容类型
字段(在jQuery的帮助下编写):

$(“#s3表单”)。关于(“提交”,函数(){
var contentTypeField=$(“输入[name='Content-Type']”,this),
fileField=$(“输入[type='file']”,this),
selectedFiles=fileField.get(0).files;
如果(files.length>0){
//我们正在上载单个文件,因此请获取第一个选定文件的类型
contentTypeField.val(selectedFiles[0].type);
}
});

发送上传/putobject请求时,字段名应该是
ContentType
而不是
Content Type
这样简单吗?@SCuzzy你让我激动了一秒钟。我试过了,得到了一个类似的错误,根据策略:额外输入字段:contenttype您的字符大小写正确吗?ie
ContentType
而不是
ContentType
@Scuzzy是的,它只是在错误响应中那样显示。我确实尝试了
ContentType
Ok错误开始抱歉,我使用了S3 PHP SDK,我的
ContentType
值似乎存储在
params
级别数组键中作为子数组,例如:
array('params'=>array('ContentType'=>image/png'))
AccessDenied根据策略无效:额外输入字段:params
这是我得到的错误。使用与您类似的请求负载更新了问题。事实上,我只是检查了我的bucket中的一个随机图像,发现内容类型也被设置为
binary/octet-stream
。如果在
标签中使用,或者与
背景img
一起使用,它可以正常工作。在标签中使用是什么意思?上传按钮?我使用了一个上传按钮,它向服务器发送一个签名请求,然后用签名凭证将请求发送到amazon,“图像不会在浏览器中查看,而是下载的”:在我看来,这才是您试图解决的真正问题。你想用哪种方式呈现图像,或者让你的应用程序的用户可以访问图像?我想他希望在使用绝对url时,图像显示在浏览器中。另外,他最初的问题是关于内容类型。我的策略设置正确,我的文件上传很好,内容类型以表单数据形式发送,但在S3控制台中检查文件时,内容类型始终为空。
    <AllowedOrigin>*</AllowedOrigin>
    <AllowedMethod>GET</AllowedMethod>
    <AllowedMethod>POST</AllowedMethod>
    <AllowedMethod>PUT</AllowedMethod>
    <MaxAgeSeconds>3000</MaxAgeSeconds>
    <AllowedHeader>Authorization</AllowedHeader>
    <AllowedHeader>Content-*</AllowedHeader>
    <AllowedHeader>Host</AllowedHeader>
    <AllowedHeader>*</AllowedHeader>