AWS S3如何将文件内嵌显示而非强制下载?

128

由于某些原因,我的S3存储桶中的文件被强制下载,而不是内联显示,所以如果我复制一个图像链接并将其粘贴到地址栏中,然后导航到它,它会促使我的浏览器下载它。相反,我实际上必须点击“打开图像”才能进入URL。

有没有改变S3提供文件的方式的方法?


当您复制图像链接时,它直接指向图像URL。浏览器只需理解执行所提供的URL即可。 - Sunil Gulabani
@SunilGulabani 但我看到有些网站使用亚马逊S3,允许您直接访问文件,而无需强制下载文件。例如,图像托管网站允许直接访问图像。我指的是直接文件路径,这是一个示例,这是我的S3存储桶中托管的文件:https://droplet-files.s3.amazonaws.com/7c32280bbcb1d3e67ac799ce9c71212f.JPG - Cl'
1
我认为在上传图片时,您提供的内容类型将是错误的。它需要是image/jpeg。请检查Content-Type:http://en.wikipedia.org/wiki/Internet_media_type。 - Sunil Gulabani
1
@SunilGulabani 我并没有在MINE类型方面发送任何数据到S3。我只是简单地执行了这个操作:$s3->putObjectFile($tmp, $bucket , $actual_image_name, S3::ACL_PUBLIC_READ),然后就完成了。 - Cl'
1
使用 $s3->create_object($bucket, $file_name, array( 'contentType' => 'image/jpeg', 'acl' => AmazonS3::ACL_PUBLIC )); - Sunil Gulabani
您可以通过将图像设为公共来解决此问题。在控制台中单击存储桶,然后单击已上传的图像并在顶部单击操作,然后在下拉菜单中选择“公共”选项。 - thomas chacko
16个回答

95
您需要定义内容类型,如下所示:
$client->putObject(array(
        'Bucket'     => 'buckname',
        'Key'        => $destination,
        'SourceFile' => $source,
        'ContentType' =>'image/jpeg', //<-- this is what you need!
        'ACL'          => 'public-read'//<-- this makes it public so people can see it
    ));

5
感谢“ContentType”=>“image/jpeg”,// <-- 这就是你需要的! - Alvin Chettiar
4
“ContentType” => “image/jpeg”,仍然会下载URL而不是在浏览器中显示。 - insivika
4
尝试在无痕浏览器中打开。我遇到了相同的问题,当我在匿名模式下打开时,它对我有用。 - marcelobrgomes
Indeed可以在新的浏览器或隐身模式下使用。 - Omar Dulaimi
我真的很讨厌S3决定数据如何呈现。我的应用程序在某些页面上有一个下载链接(因此我希望文件下载)。在其他页面上,我想在模态框中查看文件。除非您上传2个文件,否则无法使用S3的方式完成此操作。一个带有ContentType,另一个没有。为什么开发人员不能决定文件的处理方式呢? - Battousai
显示剩余2条评论

55

2
我明白了,之前我使用的是 $s3->putObjectFile($tmp, $bucket , $actual_image_name, S3::ACL_PUBLIC_READ) ,但出于某种原因,我记得我曾经使用存储桶策略来实现相同的目的。 - Cl'
2
@Cl' 你也可以在 putObject() 方法中设置 content-type(因为 putObjectFile() 现在已经过时了)。链接 - mathielo

18

若要将内容以内嵌的形式显示而非作为附件下载,您需要同时指定“Content Disposition”。

$client->putObject(array(
    'Bucket'     => 'buckname',
    'Key'        => $destination,
    'SourceFile' => $source,
    'ContentType' =>'image/jpeg', //<-- this is what you need!
    'ContentDisposition' => 'inline; filename=filename.jpg', //<-- and this !
    'ACL'          => 'public-read'//<-- this makes it public so people can see it
));

3
这对我有效。如果您想让这段代码适用于任何类型的文件,请确保使用 'ContentType' => mime_content_type($file)。 - Cary

17

如果你正在使用Python,你可以将ContentType设置如下

s3 = boto3.client('s3')

mimetype = 'image/jpeg' # you can programmatically get mimetype using the `mimetypes` module
s3.upload_file(
    Filename=local_path,
    Bucket=bucket,
    Key=remote_path,
    ExtraArgs={
        "ContentType": mimetype
    }
)

您也可以在aws cli中实现相同的功能。请注意*.jpeg。请参阅s3文档。

aws s3 cp \
      --exclude "*" \
      --include "*.jpeg" \
      --content-type="image/jpeg"  \
      --metadata-directive="REPLACE" \
      --recursive \
      --dryrun \
       s3://<bucket>/<path>/ \
       s3://<bucket>/<path>/

或者,如果您想逐个修改对象,则可以考虑使用s3api copy-object

aws s3api copy-object \
    --content-type="image/jpeg" \
    --metadata-directive="REPLACE" \
    --copy-source "<bucket>/<key>" \
    --bucket "<bucket>" \
    --key "<key>" \
    --acl public-read

6
您可以通过 AWS S3 控制台更改内容类型。

enter image description here

然后你将看到侧边弹出,使用它手动更改。

enter image description here


4
您可以尝试这个,这对我有效。
const params = {
          Bucket: 'bucket-name',
          Body: file,
          ACL: 'public-read',
          ContentType: contentType,
          ContentEncoding: 'base64',
          ContentDisposition: 'attachment',
        };

你可以从 PHP 中的 tmp 获取 contentType。 - Krish

3
我发现如果将空值传递到ContentType中,就会打开文件而不是下载。

当上传各种扩展名的文件时,这实际上非常好用。

$s3->putObject(
[
    'Bucket' => ..,
    'Key' => ..,
    'Body' => ..,
    'ContentType' => '', <---
    'ACL' => 'public-read',
]);

1
我在Python中遇到了同样的问题,加入了"bucket.put_object(Key=key,Body=strdata,ACL='public-read',ContentType='text/html')",然后它就可以工作了。 - PankajKushwaha

3
您可以尝试这个方法,如果您已经在浏览器中打开了任何URL,请尝试在隐身模式下打开,因为ContentType是在浏览器中打开的必需参数。请注意,不要删除HTML标签。
var params = {
            Bucket: config.BUCKET_NAME,
            Key: fileName,
            ContentEncoding: 'base64',
            ContentDisposition: 'inline',
            ContentType: 'image/jpeg',
            Body: buf
        };

2
我今天遇到了同样的问题,问题出在我将文件保存到s3时的Content-type属性上。我使用的是Spring Boot,在s3中的内容数据保存为application/octet-stream而非例如image/jpeg的值属性。因此,当我打开文件链接时,浏览器会下载该文件。
解决这个问题的方法是在将文件保存到s3之前更改Content-type

1

对我而言真正有效的方法是在保存S3文件之前将ContentType参数设置为image/png


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接