使用文件作为负载发出节点获取 POST 请求

问题描述 投票:0回答:1

第一次发帖,很高兴能在这里有一个社区合作!

这就是我的情况。我正在使用 Node 来整合公司合规性的自动化 - 从我们的 MDM 服务器获取报告并将其发布到我们的合规平台 (Tugboat Logic)。我们的想法是通过 AWS Lambda 定期部署它。基本逻辑是这样的:getToken 获取一个身份验证令牌,然后将其传递给 getReports。 getReports 循环遍历端点数组以从 MDM 获取报告,然后将这些报告传递到 fileReport - 然后将数据发布到端点。

问题在于最终端点需要一个文件作为负载(下面的示例 POST 请求)。我设法通过使用 fs writeFile/readFile (和延迟)使整个获取链正常工作,虽然有效,但它不能很好地转换到 Lambda 环境中。理想情况下,我只想从 getReports 获取有效负载(它以 JSON 形式出现,但也可以以文本形式接受)并将其直接推送到端点。任何有关如何清理此代码的帮助将不胜感激!

这是给我带来最大麻烦的部分(来自上一个文件)

form.append('file', x, `${reportsArray[i].name}.json`);

// Sample post request for final endpoint
curl -v --user <provided-username>:<given-password> \
 -H "X-API-KEY: <given-x-api-key>" \
 -F "collected=<date-of-evidence>" -F "file=@<local_filename_csv>;type=text/csv" \
 <given-collector-url>
//getReports.js accepts a token from an earlier function and takes fileReport as the cb
function getReports(token, cb) {
    const headers = {
        method: 'GET',
        headers: {
            'accept': 'application/json',
            'Authorization': `Bearer ${token}`
        },
        redirect: 'follow'
    }
    for (let i = 0; i < reportsArray.length; i++) {
        fetch(reportsArray[i].source, headers)
        .then(res => res.json())
        // writeFile leftover from successful deploy
        /*.then(data => fs.writeFile(`./reports/${reportsArray[i].name}.json`, data, function (err) {
            if (err) throw err;
        }))*/
        .then(res => cb(i, res))
        .catch(error => console.log('error', error))
}
};

//fileReport.js - i identifies the right endpoint from the imported array and sets filename. x is the JSON payload passed down from getReports
function fileReport(i, x) {
    const form = new FormData();
    form.append('collected', getTimestamp());
    form.append('file', x, `${reportsArray[i].name}.json`);
    fetch(`${reportsArray[i].dest}`, {
        method: 'POST',
        headers: {
            'X-API-KEY': `${process.env.TUGBOAT_X_API_KEY}`,
            'Authorization': 'Basic ' + btoa(`${process.env.TUGBOAT_USERNAME}:${process.env.TUGBOAT_PASSWORD}`)
        },
        body: form
    });
};
node.js aws-lambda fetch
1个回答
0
投票

您没有将文件正确传递至

formData

这是演示其工作原理的伪代码:

const file = fs.createReadStream("/path/to/file");
const url = "https://your.com/upload";
const fields = {}; // additional fields
const formData = new FormData();
Object.entries({ ...fields, file }).forEach(([key, value]) => {
  formData.append(key, value);
});
// built-in node fetch()
fetch(url, {
  method: "POST",
  body: formData,
}).then((response) => {
  if (!response.ok) {
    throw new Error(`Upload failed ${response.statusText}`);
  }
  console.log("file uploaded");
});

奖金:

如果您需要在浏览器中执行此操作,只需更换

file
即可使用用户选择的文件。

具体方法如下。

代替:

const file = fs.createReadStream("/path/to/file");

有一个像这样的表单元素:

<input type="file" name="myFile" onChange={(e) => documentGetLocalFile(e)} />

和这样的处理程序:

var file;
documentGetLocalFile(event) {
  if (event.target.files && event.target.files[0]) {
    file = event.target.files[0];
  }
}

然后确保您的

formData
使用此
file
代替您上面删除的
fs.createReadStream()
文件。

© www.soinside.com 2019 - 2024. All rights reserved.