The Content-Disposition response header of an S3 object can be changed dynamically by modifying the header value in the HTTP response that is returned when the object's URL is accessed.
One way to do this is to use an AWS Lambda function to intercept the request for the object's URL and modify the Content-Disposition response header before returning the response to the browser. This allows you to change the Content-Disposition value dynamically based on the request or other conditions.
Here's an example of a Lambda function that changes the Content-Disposition value based on the value of a query parameter in the request URL:
exports.handler = async (event) => {
// Get the object key and bucket from the event
const key = decodeURIComponent(event.Records[0].s3.object.key.replace(/\+/g, ' '));
const bucket = event.Records[0].s3.bucket.name;
// Get the request query parameters
const params = event.Records[0].cf.request.querystring;
// Set the Content-Disposition value based on the "download" query parameter
let contentDisposition;
if (params.includes('download=1')) {
contentDisposition = 'attachment';
} else {
contentDisposition = 'inline';
}
// Get the object from S3
const s3 = new AWS.S3();
const s3Object = await s3.getObject({
Bucket: bucket,
Key: key
}).promise();
// Create the response
const response = {
status: '200',
statusDescription: 'OK',
headers: {
'Content-Type': [{
key: 'Content-Type',
value: s3Object.ContentType
}],
'Content-Disposition': [{
key: 'Content-Disposition',
value: contentDisposition
}]
},
body: s3Object.Body
};
// Return the response
return response;
};
To use this Lambda function, you would need to set up an Amazon CloudFront distribution that points to your S3 bucket and associates the Lambda function with the distribution as an origin request trigger. Then, you can access the object's URL through the CloudFront distribution and use the download query parameter to control whether the object is rendered in the browser window or downloaded.
For example, the following URL would cause the object to be downloaded:
https://my-cloudfront-distribution.com/path/to/object.ext?download=1
And the following URL would cause the object to be rendered in the browser window:
https://my-cloudfront-distribution.com/path/to/object.ext
With this setup, you can easily switch between rendering the object in the browser window and forcing a download without having to manually change the Content-Disposition value.
Top comments (1)
this is an excellent tip!