#318 ๊ณผ ์ ์ฌํ๊ฒ ๋ ธ๋์์ axios๋ก ๊ฒ์๋ฌผ ์์ฒญ์ ํ ์ ์์ต๋๋ค. ๊ทธ๋ฌ๋ ๋ธ๋ผ์ฐ์ ์์๋ ๋์ผํ ์ฝ๋๊ฐ ์ ๋๋ก ์๋ํ๋ ๊ฒ ๊ฐ์ต๋๋ค.
const fdata = new FormData();
fdata.append('user', u);
fdata.append('hostnames', n.join(' '));
const host = localStorage.getItem('host');
const port = localStorage.getItem('port');
axios({
url: `http://${host}:${port}/hosts/remove`,
method: 'post',
data: fdata
}).then(response => {
if (response.status === 200) {
console.log(response.data);
console.log('Removed host successfully');
}
return null;
}).catch(er => console.log(er));
๋ถ์ํ๋ฉด ์๋ํฉ๋๋ค.
unirest.post(`http://${host}:${port}/hosts/remove`)
.headers({ 'Content-Type': 'multipart/form-data' })
.field('user', u)
.field('hostnames', h.join(' '))
.end(response => {
console.log(response.body);
});
์ด๊ฒ์ #789์ ์ค๋ณต์ผ๋ก ๊ฐ์ฃผ๋ ์ ์์ต๋๋ค.
nodejs์์ Axios์ ํจ๊ป form-data
ํจํค์ง๋ฅผ ์ฌ์ฉํ ์ ์์์ต๋๋ค. ๊ธฐ๋ณธ์ ์ผ๋ก FormData
๊ฐ์ ์ธํฐํ์ด์ค๋ฅผ ์ ๊ณตํฉ๋๋ค. ๊ทธ๋ฌ๋ ์์ฑํ๋ ํค๋๋ฅผ Axios์ ์๋์ผ๋ก ์ ๋ฌํ๋ ๋ฐ ์ฃผ์ํด์ผ ํฉ๋๋ค. ์๋ฅผ ๋ค์ด:
const axios = require('axios');
const FormData = require('form-data');
const form = new FormData();
// Second argument can take Buffer or Stream (lazily read during the request) too.
// Third argument is filename if you want to simulate a file upload. Otherwise omit.
form.append('field', 'a,b,c', 'blah.csv');
axios.post('http://example.org/endpoint', form, {
headers: form.getHeaders(),
}).then(result => {
// Handle resultโฆ
console.log(result.data);
});
์, form-data
ํจํค์ง๋ก ์๋ํ์ต๋๋ค. ์ด์ ๊ด์ฐฎ์ต๋๋ค. ๋์ JSON์ ๊ตฌ๋ฌธ ๋ถ์ํ๋๋ก ์๋ฒ ์ธก API๋ฅผ ๋ณ๊ฒฝํ์ต๋๋ค.
๋๊ตฐ๊ฐ nodejs ์ฑ์์ ์ํํด์ผ ํ ์์ ์ ๋ณด์ฌ์ค ์ ์์ต๋๊น?
@ar412 https://github.com/mzabriskie/axios/issues/1006#issuecomment -320165427์์ ์์ ๋ฅผ ์ ๊ณตํ๋ ค๊ณ ํ์ต๋๋ค. ์ง๋ฌธํ์ ๋ด์ฉ์ ๋ช ํํ ์ค๋ช ํด ์ฃผ์๊ฒ ์ต๋๊น?
@binki axios๊ฐ ์ผ๋ถ ๋ฐ์ดํฐ์ ํจ๊ป restapi์์ ๊ฒ์ ์์ฒญ์ ๋ณด๋ด๋ ๋ฐ ์ฌ์ฉ๋๋ ๊ฒฝ์ฐ ๋๋จธ์ง API(์ต์คํ๋ ์ค ์ ํ๋ฆฌ์ผ์ด์ ๋ด๋ถ์ ์์)์์ ํด๋น ๋ฐ์ดํฐ๋ฅผ ๊ฒ์ํ๋ ๋ฐฉ๋ฒ.
๋น์ ์ ์ด๊ฒ์ ์๋ ํ ์ ์์ต๋๋ค https://expressjs.com/en/4x/api.html#req @ar412
@ar412 Express์์ ๋ฉํฐํํธ ๋ฐ์ดํฐ๋ฅผ ์์ ํ๋ ค๋ฉด body-parser
์ ๋ฌธ์์์ ๊ถ์ฅํ๋ ๋๋ก busboy
์ ๊ฐ์ ๊ฒ์ ์ฌ์ฉํ ์ ์์ต๋๋ค. ๊ธฐ๋ณธ์ ์ผ๋ก Express์์ ์
๋ก๋๋ ํ์ผ์ ์ฒ๋ฆฌํ๋ ๋ฐฉ๋ฒ์ ๋ฐฐ์ฐ๋ ค๋ฉด Axios์ ์ ํ ๊ด๋ จ์ด ์์ผ๋ฏ๋ก ์ด ์ค๋ ๋๋ฅผ ํ์ด์ฌํนํ ๊ฒ์ฒ๋ผ ๋ค๋ฅธ ๊ณณ์์ ๋ฌผ์ด๋ณด๋ ๊ฒ์ด ์ข์ต๋๋ค ;-). ์๋ฅผ ๋ค์ด SO ์ ๋ํ ํ์ธ์ .
์ค๋ฅ ๋ฉ์์ง ๋ฐ์: form.getHeaders()๋ ํจ์๊ฐ ์๋๋๋ค.
@binki
์ด๋ด! fs.readFile(path)๋ฅผ ์ฌ์ฉํ์ฌ ๋ณ์์ ์ ์ฅ๋ ์ด๋ฏธ์ง ํ์ผ์ POSTํ๋ ค๋ hapi.js ์๋ฒ๊ฐ ์์ต๋๋ค.
FormData()๋ก ๋ณด๋ด๋ ์์
์ ์ํํ ์ ์์ต๋๋ค.
์ด๊ฒ์ ๋ด ์ฝ๋์ ๋๋ค.
fs.readFile(__dirname+'/../static/lisa_server.jpg', (error, imageData) => {
var form = new FormData()
form.append('file', imageData, {
filename: 'unicycle.jpg', // ... or:
filepath: '/../static/lisa_server.jpg',
contentType: 'image/jpg',
knownLength: 19806
})
๊ทธ๋ฐ ๋ค์ ์์ฒญ์ ๋ณธ๋ฌธ์ผ๋ก ์์์ ๋ณด๋ด๊ณ options['Content-Type'] = 'multipart/form-data'๋ฅผ ์ค์ ํฉ๋๋ค.
๋์์ฃผ์๊ฒ ์ด์?
๋งค์ฐ ๊ฐ์ฌ!
@bstolarz ๋น์ ์ดํ๊ณ ์๋ Buffer
์ ๋ฌํ๋ฉด knownLength
์ ๋ฌํ ํ์๊ฐ ์์ต๋๋ค. ๋ํ ์์ฑํ ๋ด์ฉ์ ์ฝ๋ ๊ฒฝ์ฐ( form-data
์ README ์์ ์์ ๋ณต์ฌํ์ฌ ๋ถ์ฌ filename
๋๋ filepath
์ค ํ๋๋ง ์ ๊ณตํด์ผ ํฉ๋๋ค. ๋ ๋ค ์ ๊ณตํ๋ฉด ์ ๋ฉ๋๋ค. ์ค์ ํ๋ ๊ฒ์ด ํฉ๋ฆฌ์ ์ผ ์ ์๋ ์ฌํญ์ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
filename
๋๋ filepath
contentType
(์๋ฒ์ ํน์ Content-Type ๊ฐ์ด ํ์ํ ๊ฒฝ์ฐ, ๊ทธ๋ ์ง ์์ผ๋ฉด ์๋ตํ ์ ์์).๋ด๊ฐ ์์ํ๋ ๋ฐ๋ 19806
๊ฐ์ด form-data
์ ์์ ์์ ๋ณต์ฌํ ๊ฐ์ด๊ธฐ ๋๋ฌธ์ ๋ณด๋ด๋ ์ด๋ฏธ์ง์ ํฌ๊ธฐ๊ฐ 19806
๊ฐ ์๋๋ผ๋ ๊ฒ์
๋๋ค. ์์ ์ ๋ฐ์ดํฐ์ ๋ํด ๊ณ์ฐ๋ ๊ฒ์ด ์๋๋ผ ์ ๋ฌธ์ ๋ฅผ ์ฐธ์กฐํ์ธ์. ์ด๋ก ์ธํด form-data
์์ ์์ฒด ์ค๋ฅ๊ฐ ๋ฐ์ํ๊ฑฐ๋ HTTP ์์ฒญ์ ์๋ชป๋ ๋ฐ์ดํฐ๋ฅผ ๊ธฐ๋กํ ์ ์์ต๋๋ค. axios.post()
๋ฐํ๋ Promise
์ด ๊ฑฐ๋ถ๋๊ฑฐ๋ ์์ธ๊ฐ ๋ฐ์ํ๋์ง ํ์ธํ์ต๋๊น? axios ์์ฒญ์ด ๊ฑฐ๋ถ๋๋ฉด ์ค๋ฅ ๊ฐ์ฒด์ result
ํค๊ฐ ์๋์ง ํ์ธํ๊ณ , ์์ผ๋ฉด err.result.status
๊ฐ์ด ๋ฌด์์ธ์ง ํ์ธํฉ๋๋ค. 404 ๋๋ 403์ด ์๋ 4xx ๊ฐ์ธ ๊ฒฝ์ฐ ์ด๋ ์๋ฒ๊ฐ ์๋ชป๋ ์๋ ค์ง ํฌ๊ธฐ๋ก ์ธํด ๋ฐ์ํ ์ ์๋ ์๋ชป๋ ์์ฒญ์ ๊ฑฐ๋ถํ๊ณ ์์์ ์๋ฏธํฉ๋๋ค.
@binki
๋ต๋ณ ๊ฐ์ฌํฉ๋๋ค. ๋๋ ๋น์ ์ด ์ธ๊ธ ํ ๊ฒ์ ์์ ํ์ผ๋ฏ๋ก ์ด์ ๋ด ์ฝ๋๋
fs.readFile(__dirname+'/../static/lisa_server.jpg', (error, imageData) => {
var form = new FormData()
form.append('file', imageData, {
filepath: __dirname+'/../static/lisa_server.jpg',
contentType: 'image/jpg'
})
๊ทธ๋ฌ๋ ์๋ฒ๋ 411 "๊ธธ์ด๊ฐ ํ์ํฉ๋๋ค"๋ฅผ ๋์ก์ต๋๋ค(FormData์์ ์์ ํ ์ง์๋๋ ๊ฒ์ผ๋ก ๋ณด์ด๋ fs.createReadStream๋ ์๋ํ์ง๋ง ๋์ผํ ๊ธธ์ด ์ค๋ฅ๊ฐ ๋ฐ์ํจ).
@binki
๊ฐ์ฅ ๋ฎ์ ๋ ์ด์ด์์ ํค๋ ๋ด์ฉ ๊ธธ์ด๋ฅผ ์ค์ ํ๋๋ฐ ๋ ์ด์ ํด๋น ์ค๋ฅ๊ฐ ๋ฐ์ํ์ง ์์ต๋๋ค.
์ด์ ์๋ฒ์์ 411์ ๋ฐ์ง ๋ชปํ๊ธฐ ๋๋ฌธ์ ํ๋ 400-"ํ์ผ์ด ์ ๊ณต๋์ง ์์" ์ค๋ฅ๊ฐ ๋ฐ์ํ์ต๋๋ค.
์์ฒญ์ ์ด๋ ๊ฒ ์๊ฒผ์ต๋๋ค
์์ ์์ฒญ
{ adapter: [Function: httpAdapter],
transformRequest: { '0': [Function: transformRequest] },
transformResponse: { '0': [Function: transformResponse] },
timeout: 5000,
xsrfCookieName: 'XSRF-TOKEN',
xsrfHeaderName: 'X-XSRF-TOKEN',
maxContentLength: -1,
validateStatus: [Function: validateStatus],
headers:
{ common: { Accept: 'application/json, text/plain, */*' },
delete: {},
get: {},
head: {},
post: { 'Content-Type': 'application/json' },
put: { 'Content-Type': 'application/json' },
patch: { 'Content-Type': 'application/json' },
'User-Agent': 'trojan server 1.0',
'X-Origin-Panamera': 'Staging',
'Content-Length': 25247 },
baseURL: 'https://letgoar-a.akamaihd.net/api/v1',
method: 'post',
url: 'https://<baseDomain>/api/v1/images',
data:
FormData {
_overheadLength: 218,
_valueLength: 25247,
_valuesToMeasure: [],
writable: false,
readable: true,
dataSize: 0,
maxDataSize: 2097152,
pauseStreams: true,
_released: false,
_streams:
[ '----------------------------677738213014296377492349\r\nContent-Disposition: form-data; name="file"; filename="/Users/brenda/repos/qreator2/qreator/trojan-server/src/static/lisa_server.jpg"\r\nContent-Type: image/jpg\r\n\r\n',
<Buffer ff d8 ff e0 00 10 4a 46 49 46 00 01 01 01 00 48 00 48 00 00 ff e2 11 2c 49 43 43 5f 50 52 4f 46 49 4c 45 00 01 01 00 00 11 1c 61 70 70 6c 02 00 00 00 ... >,
[Function: bound ] ],
_currentStream: null,
_boundary: '--------------------------677738213014296377492349' },
'Content-Type': 'multipart/form-data' }
์ด๊ฒ์ ํ์ธํ์๊ธฐ ๋ฐ๋๋๋ค. ๋น์ ์ด ๋ณด๊ธฐ์ ์ด๊ฒ์ด ํฉ๋ฆฌ์ ์ธ ์๊ตฌ์ฒ๋ผ ๋ณด์ ๋๊น?
๋ฏธ๋ฆฌ ๊ฐ์ฌ๋๋ฆฝ๋๋ค
@bstolarz ๊ทํ์ ๋ฌธ์ ๋ฅผ ์ฌํํ๊ธฐ ์ํด ์ต์ ์ ๋คํ์ต๋๋ค. ํ์ง๋ง ํ ์ ์์ต๋๋ค. ๋๋ ๋น์ ์ดํ๋ ์ผ์ ๋ชจ๋ฐฉํ๋ ค๊ณ ์ด ์ฝ๋๋ฅผ ์์ฑํ์ต๋๋ค. ๊ทธ๋ฌ๋ Content-Length
์๋ ์ค์ ์ ์๋์ ์ผ๋ก ์๋ตํ์ต๋๋ค. Content-Length
์ค์ ํ๊ณ ์๋ค๋ ์ฌ์ค์ด ๊ทํ์ ๋ฌธ์ ์ ๊ด๋ จ์ด ์์ ์ ์๋ค๊ณ ํ์ ํฉ๋๋ค. form-data
๊ฐ ์์์ ๊ณ์ฐํ๋๋ก ํ์ธ์. ๊ทธ๋์ form.getHeaders()
ํธ์ถํด์ผ ํฉ๋๋ค.
์ด ํ์ด์คํธ๋ฅผ ์ฐธ์กฐํ์ญ์์ค: https://gist.github.com/binki/10ac3e91851b524546f8279733cdadad . ์๋ง๋ ๋ด ์์ ์ผ์นํ๋๋ก axios.post()
๋๋ axios()
๋ฅผ ํธ์ถํ๋ ๋ฐฉ์์ ์์ ํ ์ ์์ผ๋ฉฐ ์๋ํ ๊น์?
์ฌ์ ํ ๋ฌธ์ ๊ฐ ์๋ ๊ฒฝ์ฐ ์ฝ๋๋ฅผ ์์ฒด ์คํฌ๋ฆฝํธ๋ก ์ด๋ํ๊ณ ๊ฑฐ๊ธฐ์์ ์ฌํํด ๋ณด์ญ์์ค. ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๋ ๋ฐ ๋์์ด ๋ ์ ์์ต๋๋ค. ๊ทธ๋๋ ๋ฌธ์ ๊ฐ ํด๊ฒฐ๋์ง ์์ผ๋ฉด axios()
๋๋ axios.post()
๋ํ ํธ์ถ์ ํฌํจํ์ฌ ์ ์ฒด ์ฝ๋๋ฅผ ์์ ์ผ๋ก ๊ฒ์ํ๊ณ ์ฌ๊ธฐ์ ๋งํฌํ๊ณ ๊ฐ๋ฅํ ๊ฒฝ์ฐ ์กฐ์ฌํ๊ฒ ์ต๋๋ค.
์ฌ์ ํ ์ ํ ์๋ํ์ง ์์ต๋๋ค ...
@rodrigogs ๋์์ด ํ์ํ๋ฉด ๋ ์์ธํ ์ค๋ช ํด์ผ ํฉ๋๋ค ;-).
Axios์ ๋ํ ์ด ์ ์ฉํ ์ฐ๊ตฌ๋ฅผ ๋ฐ๋๊ณ ์ต์ข ์๋ฃจ์ ์ด ์ ์๊ฒ ํจ๊ณผ์ ์ด์์ต๋๋ค( ๋งํฌ ).
๋ณต์ฌ/๋ถ์ฌ๋ฃ๊ธฐ๋ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
import fs from 'fs';
import FormData from 'form-data';
import axios from 'axios';
let data = fs.createReadStream(__dirname + '/test.jpg');
let form = new FormData();
form.append('type','image');
form.append('media',data,'test.jpg');
function getHeaders(form) {
return Promise((resolve, reject) => {
form.getLength((err, length) => {
if(err) { reject(err); }
let headers = Object.assign({'Content-Length': length}, form.getHeaders());
resolve(headers);
});
});
}
getHeaders(form)
.then((headers) => {
return axios.post(url, form, {headers:headers})
})
.then((response)=>{
console.log(response.data)
})
.catch(e=>{console.log(e)})
@westofpluto , @binki , ์ด๋ค ์๊ฐ์ด ์์ต๋๊น?
์ค๋ฅ
form.getHeaders๋ ํจ์๊ฐ ์๋๋๋ค.
@smplyjr ๋ ๋ง์ ์ปจํ
์คํธ๋ฅผ ์ ๊ณตํ๊ณ form
๋ฅผ ์ป๋ ๋ฐฉ๋ฒ์ ์๋ ค์ฃผ์๊ฒ ์ต๋๊น? ์ฝ๋๊ฐ ์์ผ๋ฉด ์ฐ๋ฆฌ๋ ๋น์ ์ด ๋ฌด์์ ํ๊ณ ์๋์ง ์ ์ ์๊ณ ๋น์ ์ ๋์ธ ์ ์์ต๋๋ค.
nodejs ์ฌ์ฉ์์ ๊ฒฝ์ฐ ๋ค์๊ณผ ๊ฐ์ด ์ฟผ๋ฆฌ ๋ฌธ์์ด lib๋ฅผ ์ฌ์ฉํ์ฌ ํด๊ฒฐํฉ๋๋ค.
const querystring = require('querystring')
axios
.post(URL, querystring.stringify(data))
.then((response) => ...)
.catch((error) => ...)
@heldrida๊ฐ ์ธ๊ธํ๋ฏ์ด ์ฟผ๋ฆฌ ๋ฌธ์์ด์ ์ฌ์ฉํ์ญ์์ค. ์ด๊ฒ์ด axios๊ฐ https://www.npmjs.com/package/axios#nodejs ์์๋ ๊ถ์ฅํ๋ ๋ฐฉ๋ฒ form-data
ํจํค์ง์๋ ์ฌ๊ธฐ์ ๋ชจ๋ ์ข
๋ฅ์ ๋ฌธ์ ๊ฐ ์์ผ๋ฉฐ ์๋ํ๋๋ก ํ๊ธฐ ์ํด ๋จธ๋ฆฌ๋ฅผ ๋ฝ๊ฒ ๋ ๊ฒ์
๋๋ค.
@heldrida @ashok-sc querystring
๋๋ qs
๋ฅผ ์ด๋ป๊ฒ ์ฌ์ฉํด์ผ ํฉ๋๊น? axios๋ฅผ ์ฌ์ฉํ์ฌ AWS Lambda์์ ํ์ผ์ ์
๋ก๋ํ๊ณ ์์ผ๋ฉฐ ๋ถ๋ช
ํ ๊ฑฐ๊ธฐ์์ File ๊ฐ์ฒด์ ์ก์ธ์คํ ์ ์์ต๋๋ค.
@bstolarz ๊ทํ์ ๋ฌธ์ ๋ฅผ ์ฌํํ๊ธฐ ์ํด ์ต์ ์ ๋คํ์ต๋๋ค. ํ์ง๋ง ํ ์ ์์ต๋๋ค. ๋๋ ๋น์ ์ดํ๋ ์ผ์ ๋ชจ๋ฐฉํ๋ ค๊ณ ์ด ์ฝ๋๋ฅผ ์์ฑํ์ต๋๋ค. ๊ทธ๋ฌ๋
Content-Length
์๋ ์ค์ ์ ์๋์ ์ผ๋ก ์๋ตํ์ต๋๋ค.Content-Length
์ค์ ํ๊ณ ์๋ค๋ ์ฌ์ค์ด ๊ทํ์ ๋ฌธ์ ์ ๊ด๋ จ์ด ์์ ์ ์๋ค๊ณ ํ์ ํฉ๋๋ค.form-data
๊ฐ ์์์ ๊ณ์ฐํ๋๋ก ํ์ธ์. ๊ทธ๋์form.getHeaders()
ํธ์ถํด์ผ ํฉ๋๋ค.์ด ํ์ด์คํธ๋ฅผ ์ฐธ์กฐํ์ญ์์ค: https://gist.github.com/binki/10ac3e91851b524546f8279733cdadad . ์๋ง๋ ๋ด ์์ ์ผ์นํ๋๋ก
axios.post()
๋๋axios()
๋ฅผ ํธ์ถํ๋ ๋ฐฉ์์ ์์ ํ ์ ์์ผ๋ฉฐ ์๋ํ ๊น์?์ฌ์ ํ ๋ฌธ์ ๊ฐ ์๋ ๊ฒฝ์ฐ ์ฝ๋๋ฅผ ์์ฒด ์คํฌ๋ฆฝํธ๋ก ์ด๋ํ๊ณ ๊ฑฐ๊ธฐ์์ ์ฌํํด ๋ณด์ญ์์ค. ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๋ ๋ฐ ๋์์ด ๋ ์ ์์ต๋๋ค. ๊ทธ๋๋ ๋ฌธ์ ๊ฐ ํด๊ฒฐ๋์ง ์์ผ๋ฉด
axios()
๋๋axios.post()
๋ํ ํธ์ถ์ ํฌํจํ์ฌ ์ ์ฒด ์ฝ๋๋ฅผ ์์ ์ผ๋ก ๊ฒ์ํ๊ณ ์ฌ๊ธฐ์ ๋งํฌํ๊ณ ๊ฐ๋ฅํ ๊ฒฝ์ฐ ์กฐ์ฌํ๊ฒ ์ต๋๋ค.
๊ณ ๋ง์์. Content-Length๋ฅผ ์ถ๊ฐํ๋ฉด ๋ด ๋ฌธ์ ๊ฐ ํด๊ฒฐ๋์์ต๋๋ค. ์ด์ FormData์ ํจ๊ป axios backend-2-backend ํธ์ถ์ ์ฌ์ฉํ ์ ์์ต๋๋ค.
const options = {
method: 'POST',
url: myUrl,
data: justJsonBody,
transformRequest: [function (data, headers) {
const formData = convertToFormData(data); // returrns ForrmData from form-data
headers['Content-Type'] = formData.getHeaders()['content-type'];
headers['Content-Length'] = formData._overheadLength;
return formData;
}]
};
์ด๊ฒ์ #789์ ์ค๋ณต์ผ๋ก ๊ฐ์ฃผ๋ ์ ์์ต๋๋ค.
nodejs์์ Axios์ ํจ๊ป
form-data
ํจํค์ง๋ฅผ ์ฌ์ฉํ ์ ์์์ต๋๋ค. ๊ธฐ๋ณธ์ ์ผ๋กFormData
๊ฐ์ ์ธํฐํ์ด์ค๋ฅผ ์ ๊ณตํฉ๋๋ค. ๊ทธ๋ฌ๋ ์์ฑํ๋ ํค๋๋ฅผ Axios์ ์๋์ผ๋ก ์ ๋ฌํ๋ ๋ฐ ์ฃผ์ํด์ผ ํฉ๋๋ค. ์๋ฅผ ๋ค์ด:const axios = require('axios'); const FormData = require('form-data'); const form = new FormData(); // Second argument can take Buffer or Stream (lazily read during the request) too. // Third argument is filename if you want to simulate a file upload. Otherwise omit. form.append('field', 'a,b,c', 'blah.csv'); axios.post('http://example.org/endpoint', form, { headers: form.getHeaders(), }).then(result => { // Handle resultโฆ console.log(result.data); });
์ฌ๊ธฐ ๋ ๋ค๋ฅธ ๋ฐฉ๋ฒ์ด ์์ต๋๋ค. ์ด๋ฌํ ๋ฐฉ์์ผ๋ก ํ๋ก์ ์์ด์ ํธ๋ฅผ ๋ฐ ๊ธฐํ ๊ตฌ์ฑ์ ์ถ๊ฐํ ์ ์์ต๋๋ค.
const axios = require('axios');
const FormData = require('form-data');
const ProxyAgent = require('proxy-agent');
const form = new FormData();
// Second argument can take Buffer or Stream (lazily read during the request) too.
// Third argument is filename if you want to simulate a file upload. Otherwise omit.
form.append('field', 'a,b,c', 'blah.csv');
axios({
method: 'POST',
url: 'http://example.org/endpoint',
data: form,
agent: new ProxyAgent("https://username:[email protected]:8080"),
headers: bodyFormData.getHeaders()
}).then(result => {
// Handle resultโฆ
console.log(result.data);
});
์ด๊ฒ์ ๋๋ฅผ ์ํด ์๋ํฉ๋๋ค.
// ES6
import axios from 'axios';
import FormData from 'form-data';
import fs from 'fs';
FormData.prototype.getHeadersWithContentLength = function getHeadersWithContentLength() {
return new Promise((resolve, reject) => {
this.getLength((err, length) =>
err ? reject(err) : resolve({ ...this.getHeaders(), 'Content-Length': length })
)
})
}
const payload = new FormData();
const form = new formidable.IncomingForm();
form.parse(req, (err, fields, { file }) => {
if (err) return;
payload.append("file", fs.createReadStream(file.path), {
filename: file.name,
contentType: file.type
});
payload.getHeadersWithContentLength().then(headers => {
api
.post(endpoint, payload, { headers })
.then(({ data }) => data)
.then(data => res.json({ data }));
});
});
์ด ๊ฒ์๋ฌผ์ ๋ชจ๋ ๊ธฐ์ฌ์์๊ฒ ๊ฐ์ฌ๋๋ฆฝ๋๋ค. Axios๋ฅผ ์ฌ์ฉํ์ฌ ๋ด form-data
์์์ ๊ฒ์ํ๋ ๋ฐ ๋ช ์๊ฐ์ ๋ณด๋ธ ํ ์ด๋ฅผ Amazon ๋ฒํท์ ๊ฒ์ํ๋ ๋ฐฑ์๋์ ์๋ฃจ์
์ ์๋์ผ๋ก content-length
....๋ฅผ ์ค์ ํ๋ ๊ฒ์ผ๋ก ๋ํ๋ฌ์ต๋๋ค.
๋ด ์ฝ๋์ ๋ฌธ์ ๊ฐ ์๋ ๋ค๋ฅธ ์ฌ๋์๊ฒ๋ ์ด๊ฒ์ด ์๋ํ๋ ๋ฐ ๋ฌธ์ ๊ฐ ์๋ ๋ค์ ์ค์ ๋์์ด ๋ ์ ์์ต๋๋ค. :)
const axios = require('axios');
const FormData = require('form-data');
// Where buffer is a file
formData.append('file', buffer);
// Added a promise version like seen in earlier comments to get this
const contentLength = await formData.getLength();
await axios(`<ENDPOINT>`, {
method: 'POST',
baseURL: <BASE_URL>,
params: {
fileName: '<FILE_NAME>.png'
},
headers: {
authorization: `Bearer <TOKEN>`,
...formData.getHeaders(),
'content-length': contentLength
},
data: formData
});
Axios๋ฅผ ์ฌ์ฉํ์ฌ ๋ด
form-data
์์์ ๊ฒ์ํ๋ ๋ฐ ๋ช ์๊ฐ์ ๋ณด๋ธ ํ ์ด๋ฅผ Amazon ๋ฒํท์ ๊ฒ์ํ๋ ๋ฐฑ์๋์ ์๋ฃจ์ ์ ์๋์ผ๋กcontent-length
....๋ฅผ ์ค์ ํ๋ ๊ฒ์ผ๋ก ๋ํ๋ฌ์ต๋๋ค.
์. ๋์ ๋ด ๋๋ฃ๋ ๋ฐ์ดํฐ๊ฐ ์ ์ถ๋์ง ์๋๋ค๊ณ ์๋ตํ๋ ๋ฐฑ์๋์ ํ์ผ์ POSTํ๋ ค๊ณ ์๋ํ ๋ ๋ช ์๊ฐ์ ๋ณด๋์ง๋ง ์์ฒญ์ ์ถ์ ํ๊ณ ๋ด์ฉ์ ๋ณผ ์ ์๊ธฐ ๋๋ฌธ์ ๋ถ๋ช ํ ๊ทธ๋ ์ต๋๋ค. ๋ฌธ์ ๋ ๋๋ฝ๋ ์ฝํ ์ธ ๊ธธ์ด ํค๋์์ต๋๋ค.
์ฐธ๊ณ ๋ก FormData์ ๋ฒํผ๋ฅผ ์ถ๊ฐํ๋ ๊ฒฝ์ฐ formData.getLengthSync()
๋ฅผ ํธ์ถํด๋ ๊ด์ฐฎ์ง๋ง ์คํธ๋ฆผ์ ์ฒ๋ฆฌํ๋ ๊ฒฝ์ฐ ๋จผ์ ํ์ผ์ fs.statSync(filePath).size
๋๋ ์๋ฅผ ๋ค์ด ์คํธ๋ฆผ์ด ์์ฒญ์ด๋ ์์ผ ๋ฑ์์ ์ค๋ ๊ฒฝ์ฐ์ ๊ฐ์ด ๋ค๋ฅธ ๋ฐฉ์์ผ๋ก ์ ์ฒด ํฌ๊ธฐ๋ฅผ ๊ฐ์ ธ์ต๋๋ค(์
์คํธ๋ฆผ์ ์ฝํ
์ธ ๊ธธ์ด ํค๋์์). ์คํธ๋ฆผ์ด ๋์ ๋์คํฌ์์ ์ค๋ ๊ฒฝ์ฐ fs.statSync(filePath).size
๋ ํฌ๊ธฐ๋ฅผ ๋ฐ์ดํธ ๋จ์๋ก ์ ๊ณตํ๋ฏ๋ก FormData์ ์ถ๊ฐํ ๋ knownLength์ ์ถ๊ฐํ ์ ์์ต๋๋ค.
formData.append("file", fs.createReadStream(filePath), { filename: 'whatever.pdf', knownLength: fs.statSync(filePath).size });
๋ฌผ๋ก ๋ชจ๋ Sync ๋ฉ์๋๋ async ๋ฉ์๋์ await ํค์๋๋ก ์ ํ๋ ์ ์์ต๋๋ค.
// Added a promise version like seen in earlier comments to get this const contentLength = formData.getLength();
์ค์ ๋ก formData ์ ์ await
๋ฅผ ์์ด ๋ฒ๋ฆฐ ๊ฒ ๊ฐ์ต๋๋ค ...
๊ฐ์ฅ ์ ์ฉํ ๋๊ธ
์ด๊ฒ์ #789์ ์ค๋ณต์ผ๋ก ๊ฐ์ฃผ๋ ์ ์์ต๋๋ค.
nodejs์์ Axios์ ํจ๊ป
form-data
ํจํค์ง๋ฅผ ์ฌ์ฉํ ์ ์์์ต๋๋ค. ๊ธฐ๋ณธ์ ์ผ๋กFormData
๊ฐ์ ์ธํฐํ์ด์ค๋ฅผ ์ ๊ณตํฉ๋๋ค. ๊ทธ๋ฌ๋ ์์ฑํ๋ ํค๋๋ฅผ Axios์ ์๋์ผ๋ก ์ ๋ฌํ๋ ๋ฐ ์ฃผ์ํด์ผ ํฉ๋๋ค. ์๋ฅผ ๋ค์ด: