3

我只是(或不)试图从我的亚马逊存储桶中强制下载 JPG,如下所示:

function get_s3_signed_url($bucket, $resource, $AWS_S3_KEY, $AWS_s3_secret_key, $expire_seconds) {
    $expires = time()+$expire_seconds;

    $string_to_sign = "GET\n\n\n{$expires}\n/".str_replace(".s3-eu-west-1.amazonAWS.com","", $bucket)."/$resource";
    $signature = urlencode(base64_encode((hash_hmac("sha1", utf8_encode($string_to_sign), $AWS_s3_secret_key, TRUE))));

    $authentication_params = "AWSAccessKeyId=".$AWS_S3_KEY;
    $authentication_params.= "&Expires={$expires}";
    $authentication_params.= "&Signature={$signature}";

    return $link = "https://s3-eu-west-1.amazonAWS.com/{$bucket}/{$resource}?{$authentication_params}";
}

$url = get_s3_signed_url( $aws_bucketName, 'website-hires-photos/photo/'.$filename, $aws_access_key_id, $aws_s3_secret, 30);

header('Content-Type: images/jpg');
header("Content-Transfer-Encoding: Binary");
header('Content-Description: File Transfer'); 
header("Content-disposition: attachment; filename=\"".$url."\""); 
readfile($url);

但是我收到了很多行话,就像这样:

zóPcg”<code>îZ~ØsÍêïJ#£Aq$ÓÒ†Nkèk�Á+bÊ˛«∏k.≠ªÄ‡K©~‰˚FπæÜv§›†˘π#kGGº~{Ölüûˡ�¢¨Ü±S_π̧ àfi˛[Ô FL€≤˛«^^/P˙{ß“Ì∫}_˚k'˝cg˙UF–Ò[2kK\OÉá∂¥'_PÓı`oà˘N‰ï˚_ˇ“Ûzöw4∏í x ©ì©”∫—Œ£üä~¸~ŸÓk£√¯Ö•áıw¨Â“ÀÈ∆äüÓ≠÷9¨º—c∑=üÿYò~ä^€</p>

这似乎是一本很有趣的书,但我没有时间坐下来阅读它。现在,文件“某种”下载,它说它的大小是 748kb,这是这张照片的正确大小。但是,我的机器不知道文件类型,所以我在文本编辑器中打开它,它给出了上述垃圾。

请告诉我我做错了什么。在此之前或之后,我不会在屏幕上回显任何内容。我在顶部有两个包含请求,这个函数以及 headers 和 readfile 函数。

修复更新:

这完全是因为预签名的 AWS S3 链接在正确的.JPG 扩展名之后具有查询字符串值.JPG?AWSAccessKeyID=345wrdwf。因此,下载时,它无法识别扩展名。我通过为标头创建一个唯一的 URL 来解决这个问题,如下所示:

$headerURL = array_shift(explode('?', basename($url)));

这会剥离文件名之前和之后的所有内容。所以我最终得到了这样的结果:

$url = get_s3_signed_url( $aws_bucketName, 'website-hires-photos/photo/'.$filename, $aws_access_key_id, $aws_s3_secret, 10);
$headerURL = array_shift(explode('?', basename($url)));
header("Content-Transfer-Encoding: binary");
header("Content-Type: image/jpg");
header('Content-Description: File Transfer');
header("Content-Disposition: attachment; filename=".$headerURL);
readfile($url);
4

1 回答 1

5

回答了我自己的问题,但利用其他人的知识使我达到了这一点,所以谢谢。

这完全是因为预签名的 AWS S3 URL 在正确的.JPG 扩展名之后具有查询字符串值/photo.jpg?AWSAccessKeyID=345wrdwf。因此,下载时,它无法识别文件扩展名。我通过为标头创建一个唯一的 URL解决这个问题,如下所示:

$headerURL = array_shift(explode('?', basename($url)));

这会剥离文件名之前和之后的所有内容。所以我最终得到了这样的结果:

$url = get_s3_signed_url( $aws_bucketName, 'website-hires-photos/photo/'.$filename, $aws_access_key_id, $aws_s3_secret, 10);
$headerURL = array_shift(explode('?', basename($url)));
header("Content-Transfer-Encoding: binary");
header("Content-Type: image/jpg");
header('Content-Description: File Transfer');
header("Content-Disposition: attachment; filename=".$headerURL);
readfile($url);

并保存为正确的照片。呜呜呜!

这教会了我一些今天有价值的东西。我不知道您可以在标题附件字段中添加您喜欢的任何文件名。无论您添加什么,文件在用户接受下载时保存的内容。因此,放置我的公司名称和下载参考是一个巨大的奖励。

于 2012-07-30T03:45:48.823 回答