简体   繁体   中英

How do I upload a file to a pre-signed URL in AWS?

Problem

I have a pre-signed URL from AWS. I need to upload a file to it. How do I do this?

(I have to use a pre-signed URL. I'm calling the createUpload API for Device Farm , which returns one.)

AWS Documentation gives examples on how to do this in Java, .NET and Ruby . JavaScript is missing.

Attempt 1

I adapted the example here .

const axios = require('axios');
const FormData = require('form-data');

function uploadFile(url, file) {
    if (typeof url !== 'string') {
        throw new TypeError(`Expected a string, got ${typeof url}`);
    }
    const formData = new FormData();
    formData.append(file,file)
    const config = {
        headers: {
            'content-type': 'multipart/form-data'
        }
    }
    return  axios.post(url, formData,config)
}

However I get this error:

The request signature we calculated does not match the signature you provided. Check your key and signing method.

Attempt 2

I got it working with cURL. However, I don't want a dependency on cURL.

const Promise = require('bluebird');
const cmd = require('node-cmd');
const getAsync = Promise.promisify(cmd.get, { multiArgs: true, context: cmd }); 

async function uploadFile(url, fileName) { 
    await throwIfCurlNotInstalled();
    console.log('uploadFile: Uploading file', {
        fileName
    });
    const command = `curl -T ${fileName} "${url}"`;
    try {
        let result = await getAsync(command);
        result.forEach(line => console.log(line));
        console.log('uploadFile: File uploaded', {
            fileName,
        });
    } catch (e) {
        console.error('uploadFile: Error uploading file', {
            fileName
        });
        console.error(e);
    }
}
async function throwIfCurlNotInstalled() {
    try {
        await getAsync(`curl -V`);
    } catch (e) {
        throw 'curl is not installed';
    }
}

The solution was surprisingly simple:

const rp = require('request-promise');
const fs = require('fs');

async function uploadFile(url, fileName) {
    let options = {
        method: 'PUT',
        uri: url,
        body: fs.readFileSync(fileName),
    };

    return rp(options);
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM