Upload files to Amazon S3 from the browser using pre-signed urls

May 25, 2018 · 6 min read
npm install aws-sdk
const AWS = require(‘aws-sdk’);
const s3 = new AWS.S3({accessKeyId : config.aws_access_key_id, secretAccessKey : config.aws_secret_access_key, useAccelerateEndpoint: true});
const config = require(‘./config.js’).get(process.env.NODE_ENV);
sudo NODE_ENV=local node server
sudo NODE_ENV=dev node server
sudo NODE_ENV=prod node server
app.get(‘/generatepresignedurl’, function(req,res){
var fileurls = [];

/*setting the presigned url expiry time in seconds, also check if user making the request is an authorized user for your app (this will be specific to your app’s auth mechanism so i am skipping it)*/
const signedUrlExpireSeconds = 60 * 60;
const myBucket = config.s3bucketname;
const myKey = ‘api/uploads/’ + ‘test.csv’;
const params = {Bucket: myBucket, Key: myKey, Expires: signedUrlExpireSeconds, ACL: ‘bucket-owner-full-control’, ContentType:’text/csv’};
s3.getSignedUrl(‘putObject’, params, function (err, url){
console.log(‘Error getting presigned url from AWS S3’);
res.json({ success : false, message : ‘Pre-Signed URL error’, urls : fileurls});
fileurls[0] = url;
console.log(‘Presigned URL: ‘, fileurls[0]);
res.json({ success : true, message : ‘AWS SDK S3 Pre-signed urls generated successfully.’, urls : fileurls});
Encryption settings
“Version”: “2012–10–17”,
“Id”: “<policy-id>”,
“Statement”: [
“Sid”: “<sid>”,
“Effect”: “Allow”,
“Principal”: {
“AWS”: “arn:aws:iam::<awsaccount>:user/<awsusername>”
“Action”: “s3:*”,
“Resource”: “arn:aws:s3:::<s3-bucket-name>”
<?xml version=”1.0" encoding=”UTF-8"?>
<CORSConfiguration xmlns=”http://s3.amazonaws.com/doc/2006-03-01/">
onSubmit() {//call node/express api endpoint to generate presignedurl/*fileService is nothing but a service injected into your angular component’s constructor like this constructor(private fileService: FileService) {}*/this.fileService.getpresignedurls().subscribe(res =>{console.log(res); // Your res object will have your pre-signed url//my res object is structured as success: boolean, message: string, urls: Array<string>;if(res.success){const fileuploadurl = res.urls[0];//once the presigned url is received the next service call will upload the file.this.fileService.uploadfileAWSS3(fileuploadurl, ‘text/csv’, this.yourform.get(‘filedetails’).value).subscribe((event: HttpEvent<any>) => {//handle HttpEvent progress or response and update view});}});}
getpresignedurls(): Observable<PreSignedURL>{
let getheaders = new HttpHeaders().set(‘Accept’, ‘application/json’);
return this.http.get<PreSignedURL>(this.getpresignedurlsserver, { headers: getheaders});
uploadfileAWSS3(fileuploadurl, contenttype, file): Observable<any>{ //this will be used to upload all csv files to AWS S3 const headers = new HttpHeaders({‘Content-Type’: contenttype});
const req = new HttpRequest(
headers: headers,
reportProgress: true, //This is required for track upload process
return this.http.request(req);

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade