Я пытаюсь загрузить изображение из внешнего интерфейса, post
его с аксиомами в серверную часть (node.js), а затем оттуда post
снова в сервис изображений GroupMe.
Главное - избегать использования токена API во внешнем интерфейсе, поэтому я пытался сначала отправить запрос на серверную часть, а затем отправить фактический запрос API в службу изображений GroupMe, которая ожидает получить FormData изображения. и отправляет обратно преобразованный URL-адрес изображения.
Я попытался отправить FormData напрямую в службу изображений GroupMe из внешнего интерфейса, и все работает нормально. Однако для этого мне пришлось хранить токен во внешнем интерфейсе, что, я считаю, не очень хорошая идея.
Рабочий код ниже:
let config = {
headers : {
'X-Access-Token': myToken,
'Content-Type' : 'multipart/form-data'
}
}
let fd = new FormData()
fd.append('name', 'image')
fd.append('file', fileToUpload)
axios.post'(https://image.groupme.com/pictures', fd, config)
.then((response)=>{
console.info(response)
})
.catch(err =>{
console.info(err.response)
})
Вместо этого мне нужно отправить запрос на серверную часть следующим образом:
axios.post(process.env.baseUrl+'/messengerRequests/upload-file/', fd, config)
.then((response)=>{
console.info(response)
})
.catch(err =>{
console.info(err.response)
})
И теперь в бэкэнде каким-то образом можно получить эти данные FormData, а затем создать еще один почтовый запрос к сервису изображений GroupMe, как я изначально сделал во внешнем интерфейсе.
sendMessage: async(req, res) => {
axios.post('https://image.groupme.com/pictures', ???, config)
.then((response)=>{
res.send(response)
})
.catch(err =>{
console.info(err.response)
})
}
Я не знаю, где это появляется в запросе axios. В req.body
или req.params
нет ничего, поэтому я не могу просто передать это дальше для следующего post
.
Есть ли способ снова передать эти FormData? Или, может быть, есть способ безопасно использовать токен во фронд-энде?
Если вы используете Express, вам понадобится что-то для обработки FormData. Раньше я использовал множитель для чего-то подобного. Мне пришлось сохранить файлы в локальном хранилище, а затем повторно отправить файл с помощью axios.
Таким образом, разместить изображение в GroupMe с помощью Node.js и Express/Multer/Request должно быть относительно просто. Я выбрал Request, а не Axios на серверной части, так как я лучше знаком с API, но на самом деле это та же разница.
Код Node.js (index.js)
const request = require("request");
const express = require("express");
const multer = require("multer");
const upload = multer();
const app = express();
const port = 3000;
const myToken = "" // Your API token goes here.
app.use(express.static("./"));
/* Here we take the image from the client and pass it on to GroupMe */
app.post("/uploadFile", upload.any(), (req, res) => {
sendImageToGroupMe(req, res);
});
function sendImageToGroupMe(req, res) {
const options = {
uri: "https://image.groupme.com/pictures",
body: req.files[0].buffer,
method: "POST",
headers: {
"X-Access-Token" : myToken
}
}
request(options, (err, response, body) => {
console.info("Request complete: Response: ", body);
if (err) {
console.error("Request err: ", err);
res.status(500).send("Upload failed: ", err.message);
} else {
res.status(201).send("Upload successful: GroupMe response: " + body);
}
});
}
app.listen(port);
Сторона клиента
index.html
<!DOCTYPE html>
<html>
<head>
<meta charset = "utf-8">
<script src = "https://unpkg.com/axios/dist/axios.min.js"></script>
<script>
function uploadFile() {
var fileToUpload = document.querySelector('input[type=file]').files[0];
let config = {
headers : {
'Content-Type' : 'multipart/form-data'
}
}
let fd = new FormData()
fd.append('name', 'image')
fd.append('file', fileToUpload)
axios.post('http://localhost:3000/uploadFile', fd, config)
.then((response)=>{
console.info("Image posted successfully: ", response);
showOutput("Image posted successfully: " + response.data);
})
.catch(err =>{
console.error("Image post failed: ", err)
showOutput("Image post failed!");
})
}
function showOutput(html) {
document.getElementById("output").innerHTML = html;
}
</script>
</head>
<body style = "margin:50px">
<input type = "file" onchange = "uploadFile()"><br>
<p id = "output"></p>
</body>
</html>
Все файлы находятся в одном каталоге. Вы можете перейти к http://локальный: 3000/, чтобы протестировать код index.html, он будет обслуживаться сервером Node.js в виде статического файла.
Я получаю ответ, как показано ниже, от API GroupMe:
{
"payload": {
"url": "https://i.groupme.com/157x168.png.940f20356cd048c98478da2b181ee971",
"picture_url": "https://i.groupme.com/157x168.png.940f20356cd048c98478da2b181ee971"
}
}
Мы будем обслуживать локально на порту 3000, поэтому для запуска сервера:
node index.js
Я просто буферизирую файл в памяти на сервере. Вы также можете настроить multer для сохранения на диск, если это необходимо.
А нет, это здорово. Я просто не был уверен в этой строке: app.use(express.static("./"));
О, это только для обслуживания любого статического контента, например. индекс.html.
Если вы не отправляете это из внешнего интерфейса, вам придется установить пакет form-data
в NodeJS. Также вам может понадобиться указать boundary
в multipart/form-data
Привет, спасибо за ваш ответ. То есть вы на самом деле сохраняете файл на сервере перед его отправкой в API GroupMe, верно?