[英]Fetching image from URL and uploading to another via POST in NodeJS
在以下代碼段中,我使用node-fetch和form-data首先從遠程 URL 檢索圖像文件,然后將其上傳到 S3 存儲桶(在不同的腳本中使用aws-sdk和multer ):
import fetch from 'node-fetch';
import fs from 'fs';
import FormData from 'form-data';
const form = new FormData();
const processProfileImg = (imageURL, userID) => {
fetch(imageURL, userID)
.then((response) => {
const dest = fs.createWriteStream(`./temp/${userID}.jpg`);
response.body.pipe(dest);
})
.then((dest) => {
form.append('profileImage', fs.createReadStream(`./temp/${userID}.jpg`));
fetch(`https://www.schandillia.com/upload/profile-image?userID=${userID}`, { method: 'POST', body: form })
.then(response => response.json())
.then(json => console.log(json));
});
};
export default processProfileImg;
問題是,這涉及一個中間步驟,即首先在檢索時將文件存儲在本地,然后再由form-data
函數將其用於 POST。 有沒有辦法完全繞過這一步? 我不想將文件保存在本地,我只想從遠程 URL 中提取它並將其 POST 到上傳路由,而無需創建本地文件。
更新:在稍微修改片段以實現 Fransebas(第一個答案)的建議並避免異步問題后,我遇到了一個新問題:本地保存的圖像沒問題,但上傳到 S3 的副本被部分切斷!
附加代碼:處理 POST 上傳的路由https://www.schandillia.com/upload/profile-image如下,當我嘗試使用 Postman 上傳文件時,它運行良好。
import dotenv from 'dotenv';
import express from 'express';
import aws from 'aws-sdk';
import multerS3 from 'multer-s3';
import multer from 'multer';
import path from 'path';
dotenv.config();
const router = express.Router();
// Set up S3
const s3 = new aws.S3({
accessKeyId: process.env.IAM_ACCESS_KEY_ID,
secretAccessKey: process.env.IAM_SECRET_ACCESS_KEY,
});
const checkFileType = (file, cb) => {
// Allowed ext
const filetypes = /jpeg|jpg/;
// Check ext
const extname = filetypes.test(path.extname(file.originalname).toLowerCase());
// Check mime
const mimetype = filetypes.test(file.mimetype);
if (mimetype && extname) {
return cb(null, true);
}
return cb('Error: JPEG Only!');
};
// Single Upload
const profileImgUpload = multer({
storage: multerS3({
s3,
contentType: multerS3.AUTO_CONTENT_TYPE,
bucket: `${process.env.S3_BUCKET_NAME}/w`,
acl: 'public-read',
key(req, file, cb) {
cb(null, req.query.userID + path.extname(file.originalname));
},
}),
limits: { fileSize: 2000000 }, // In bytes: 2000000 bytes = 2 MB
fileFilter(req, file, cb) {
checkFileType(file, cb);
},
}).single('profileImage');
router.post('/profile-image', (req, res) => {
profileImgUpload(req, res, (error) => {
if (error) {
console.log('errors', error);
res.json({ error });
} else if (req.file === undefined) {
// If File not found
console.log('Error: No File Selected!');
res.json('Error: No File Selected');
} else {
// If Success
const imageName = req.file.key;
const imageLocation = req.file.location;
// Save the file name into database into profile model
res.json({
image: imageName,
location: imageLocation,
});
}
});
});
// End of single profile upload
// We export the router so that the server.js file can pick it up
module.exports = router;
我沒有使用發送數據的特定方式(我更喜歡ajax),但是通過查看您的示例,我想您可以跳過本地保存圖像。 如果看到fs.createReadStream
則會創建一個讀取流。 尋找從您獲得的內容中創建讀取流的方法。
另外,我覺得你應該把你送代碼中的then
所以你不必異步問題。 例如,如果您的用於發送數據的代碼位於內, then
可以使用response.body
創建流。
差不多了,但是您仍在使用該文件,我想您可以使用其他類似方式將其歸檔
import fetch from 'node-fetch';
import fs from 'fs';
import FormData from 'form-data';
const form = new FormData();
const processProfileImg = (imageURL, userID) => {
fetch(imageURL, userID)
.then((response) => {
// Use response.body directly, it contains the image right?
form.append('profileImage', response.body);
fetch(`https://www.schandillia.com/upload/profile-image?userID=${userID}`, { method: 'POST', body: form })
.then(response => response.json())
.then(json => console.log(json));
});
};
export default processProfileImg;
如果我正確理解fetch
文檔,則response.body
已經是一個流。
這對我有用:
const axios = require('axios')
const FormData = require('form-data');
//Get image
let imageResponse = await axios({
url: imageUrl,
method: 'GET',
responseType: 'arraybuffer'
})
//Create form data
const form = new FormData()
form.append('image', imageResponse.data, {
contentType: 'image/jpeg',
name: 'image',
filename: 'imageFileName.jpg'
})
//Submit form
let result = await axios({
url: serverUrl,
method: "POST",
data: form,
headers: { "Content-Type": `multipart/form-data; boundary=${form._boundary}` }
})
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.