I have an S3 bucket having PDF files as objects and all of them are private. I create an S3 Presigned URL programmatically to get the object. It works fine. Now, I want it to be previewable as a PDF. Every object already has a Content-Type
header set to application/pdf
. Now, if I set the response-content-disposition
header as a query parameter, it gets set but doesn't override the already existing Content-disposition
header, instead, it creates a new one. If I set the Content-Disposition
header in the metadata of the S3 object instead of adding it in the S3 Presigned URL as a query parameter, it still shows 2 headers. Is this some kind of bug on the AWS S3 side?
Below is the screenshot of the Response Header for reference.
Any help will be much appreciated. Thanks.
I have solved this issue using the latest API available for this thing from AWS SDK for NodeJS using the following code:
const aws = require('aws-sdk');
const AWS_SIGNATURE_VERSION = 'v4';
const s3 = new aws.S3({
accessKeyId: <aws-access-key>,
secretAccessKey: <aws-secret-access-key>,
region: <aws-region>,
signatureVersion: AWS_SIGNATURE_VERSION
});
/**
* Return a signed document URL given a Document instance
* @param {object} document Document
* @return {string} Pre-signed URL to document in S3 bucket
*/
const getS3SignedDocumentURL = (docName) => {
const url = s3.getSignedUrl('getObject', {
Bucket: <aws-s3-bucket-name>,
Key: <aws-s3-object-key>,
Expires: <url-expiry-time-in-seconds>,
ResponseContentDisposition: `attachment; filename="${docName}"`
});
return url;
};
/**
* Return a signed document URL previewable given a Document instance
* @param {object} document Document
* @return {string} Pre-signed URL to previewable document in S3 bucket
*/
const getS3SignedDocumentURLPreviewable = (docName) => {
const url = s3.getSignedUrl('getObject', {
Bucket: <aws-s3-bucket-name>,
Key: <aws-s3-object-key>,
Expires: <url-expiry-time-in-seconds>,
ResponseContentDisposition: `inline; filename="${docName}"`
});
return url;
};
module.exports = {
getS3SignedDocumentURL,
getS3SignedDocumentURLPreviewable
};
Note: Don't forget to replace the placeholders (<...>) with actual values to make it work.