如何将文件上传到 AWS 中的预签名 URL?

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

问题

我有一个来自 AWS 的预签名 URL。我需要上传一个文件给它。我该怎么做?

(我必须使用预签名 URL。我正在调用 createUpload API for Device Farm,其中 returns 一个。)

AWS Documentation gives examples on how to do this in Java, .NET and Ruby。 JavaScript 丢失。

尝试 1

我改编了例子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)
}

但是我得到这个错误:

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

尝试 2

我用 cURL 得到了它。但是,我不想依赖 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';
    }
}

解决方案非常简单:

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