AWS S3 display file inline instead of force download

Amazon Web-ServicesAmazon S3

Amazon Web-Services Problem Overview


For some reason files in my S3 bucket are being forced as downloads instead of displaying in-line so if I copy an image link and paste it into address bar and then navigate to it, it will promote my browser to download it. Instead I actually have to click on open image to go to the url.

Any ways to change the way files are served from S3

Amazon Web-Services Solutions


Solution 1 - Amazon Web-Services

$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
	));

Solution 2 - Amazon Web-Services

You need to change the Content-Type. From the S3 console, right click on the object and select Properties then it's under Metadata. You can also do it programmatically: http://docs.amazonwebservices.com/AWSSDKforPHP/latest/index.html#m=AmazonS3/change_content_type

Solution 3 - Amazon Web-Services

You need to specify Content Disposition as well for inline instead attachment .

$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
));

Solution 4 - Amazon Web-Services

if you are using python, you can set ContentType as follows

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
    }
)

You can also achieve the same in aws cli. Note *.jpeg Check s3 documentation

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

Alternatively if you'd want to do modify one object at a time you might want to use 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

Solution 5 - Amazon Web-Services

You can change the content type from the AWS S3 Console too.

enter image description here

Then you will get to see the side pop up, use that to change it manually.

enter image description here

Solution 6 - Amazon Web-Services

You can try this one, this works for me.

const params = {
          Bucket: 'bucket-name',
          Body: file,
          ACL: 'public-read',
          ContentType: contentType,
          ContentEncoding: 'base64',
          ContentDisposition: 'attachment',
        };

Solution 7 - Amazon Web-Services

You can try this one, ContentType is compulsory for open in a browser if you have already opened any URL on the browser then try in incognito.

var params = {
            Bucket: config.BUCKET_NAME,
            Key: fileName,
            ContentEncoding: 'base64',
            ContentDisposition: 'inline',
            ContentType: 'image/jpeg',
            Body: buf
        };

Solution 8 - Amazon Web-Services

I found out that if we pass an empty value to ContentType it will open the file instead of downloading.

This is actually nice when uploading files of all kind of extensions.

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

Solution 9 - Amazon Web-Services

I had the same problem today. The problem was the Content-type property, when I was saving the file in s3. I am using Spring Boot, and content data in s3 was saving application/octet-stream in the value properties instead of image/jpeg, for example. Therefore, when I opened the file link, the browser downloaded the file.

The solution for this problem is to change the Content-type before saving the file in s3 !

Solution 10 - Amazon Web-Services

In case someone who is using Java SDK is finding a solution for this, you need to set content type to ObjectMetaData.

ObjectMetadata objectMetadata = new ObjectMetadata();
objectMetadata.setContentType("image/png");
        
s3client.putObject(new PutObjectRequest
    (bucketName, fileName + ".png", inputStream, 
     objectMetadata).withCannedAcl(CannedAccessControlList.PublicRead));

Solution 11 - Amazon Web-Services

If you open it in incognito it will work other than that it will not work for some reason.

Solution 12 - Amazon Web-Services

Use these two properties to force browsers to inline the file from s3:

'ResponseContentType' & 'ResponseContentDisposition'

You can use them in the getCommand when generating a signed URL

$cmd = $s3Client->getCommand('GetObject', [
        'Bucket' => $bucket_name,
        'Key' => $filename,
        'ResponseContentType' =>  get_mime_type($filename),
        'ResponseContentDisposition' => 'inline; filename='.$user_filename
    ]);
   

get_mime_type is just my custom function to return mime type using the file name

This is what I used when I faced the same problem, I have millions of files in my s3 bucket and I couldn't change the mime type individually in console

Solution 13 - Amazon Web-Services

What really worked for me was to set the ContentType params to image/png before saving the S3 file.

Solution 14 - Amazon Web-Services

After 2 days of fighting, this is the code I want.
Here is the code for anyone who uses "generate_presigned_post" in python

s3 = boto3.client('s3',
                  aws_access_key_id="<aws_access_key_id>",
                  aws_secret_access_key="<aws_secret_access_key>",
                  config=Config(
                      region_name="<region_name>",
                      signature_version="<signature_version>"
                  ))

key = 'bbb.png'

creds = s3.generate_presigned_post(
    Bucket="<Bucket>",
    Key=key,
    Fields={"Content-Type": "image/png"},
    Conditions=[{"Content-Type": "image/png"}],
    ExpiresIn=3600)

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionCl&#39;View Question on Stackoverflow
Solution 1 - Amazon Web-ServicesNeoView Answer on Stackoverflow
Solution 2 - Amazon Web-ServicesgregbeatyView Answer on Stackoverflow
Solution 3 - Amazon Web-ServicesAlin RazvanView Answer on Stackoverflow
Solution 4 - Amazon Web-ServicesAnthony AwuleyView Answer on Stackoverflow
Solution 5 - Amazon Web-ServicesNerdy SidView Answer on Stackoverflow
Solution 6 - Amazon Web-Servicesvishal pankhaniyaView Answer on Stackoverflow
Solution 7 - Amazon Web-ServicesAnkit Kumar RajpootView Answer on Stackoverflow
Solution 8 - Amazon Web-ServicesLinesofcodeView Answer on Stackoverflow
Solution 9 - Amazon Web-ServicesAdriano RabelloView Answer on Stackoverflow
Solution 10 - Amazon Web-ServicesvigamageView Answer on Stackoverflow
Solution 11 - Amazon Web-Serviceskd12345View Answer on Stackoverflow
Solution 12 - Amazon Web-ServicesMike T.View Answer on Stackoverflow
Solution 13 - Amazon Web-ServicesClauView Answer on Stackoverflow
Solution 14 - Amazon Web-ServicesTài HatranducView Answer on Stackoverflow