TAR μμΉ΄μ΄λΈ λ΄λΆμ μλ νμΌ(λ©ν°ννΈ POST μμ² μ¬μ©)μ μ
λ‘λνλ €κ³ νμ΅λλ€( tar-stream
λΌμ΄λΈλ¬λ¦¬λ₯Ό μ¬μ©νμ¬ TAR μμΉ΄μ΄λΈ λ΄λΆμ νΉμ νμΌλ‘ μ€νΈλ¦Όμ κ°μ Έμ΄). κ·Έλ¬λ νμ ECONNRESET μ€λ₯λ‘ μ€ν¨ν©λλ€. μ½κ°μ μ€ν νμ fs.createReadStream
λ‘ μ§μ ꡬμ±λ μ€νΈλ¦Όλ§ μ
λ‘λν μ μλ κ²μ²λΌ 보μ΄λ©° λ€λ₯Έ λͺ¨λ μ€νΈλ¦Όμ λν΄μλ κ΄λ ¨ μλ μ€λ₯λ‘ μ€ν¨ν©λλ€.
λ€μμ λ¬Έμ λ₯Ό μ¬ννλ μ΅μνμ μμ
λλ€. PassThrough
μ€νΈλ¦Όμ΄ formData
μ μ λ¬λλ©΄ λ€μ μ€λ₯κ° λ°μν©λλ€.
ERROR { Error: socket hang up
at createHangUpError (_http_client.js:254:15)
at Socket.socketOnEnd (_http_client.js:346:23)
at emitNone (events.js:91:20)
at Socket.emit (events.js:185:7)
at endReadableNT (_stream_readable.js:974:12)
at _combinedTickCallback (internal/process/next_tick.js:74:11)
at process._tickCallback (internal/process/next_tick.js:98:9) code: 'ECONNRESET' }
μ¬κΈ°λ μ¬λ:
var http = require('http');
http.createServer(function (request, response) {
request.on('data', function(chunk) {
console.log(chunk.length);
});
request.on('end', function() {
response.writeHead(200, "OK", {'Content-Type': 'text/html'});
response.end();
});
}).listen(8077);
κ³ κ°:
var request = require('request');
var fs = require('fs');
var PassThrough = require('stream').PassThrough;
var rs = fs.createReadStream('some_file.bin'), pt = new PassThrough();
rs.pipe(pt);
request({
'method': 'POST',
'url': 'http://127.0.0.1:8077',
'formData': {
'uploaded_file': pt
}
}, function (err, httpResponse, body)
{
if (err)
console.log('ERROR', err);
else
console.log({ 'statusCode': httpResponse.statusCode, 'body': body });
});
μ ν¨ν λ©ν°ννΈ μμ²μΌλ‘ μ
λ‘λνκΈ° μν΄ μ½κΈ° μ€νΈλ¦Όμμ Buffer
λ₯Ό λννλ €κ³ ν λ λμΌν λ¬Έμ κ° λ°μν©λλ€.
λλ λν μ΄ λ¬Έμ λ₯Ό ν΄κ²°νκΈ° μν΄ μΌλ§ λμ λ°©λ²μ μ°ΎμΌλ €κ³ λ Έλ ₯νμΌλ©° μμμ μΈκΈν κ²κ³Ό λμΌν λ¬Έμ λ₯Ό κ²½ννμ΅λλ€. λꡬλ μ§ μ΄μ λν ν΄κ²° λ°©λ²μ μ°Ύμμ΅λκΉ? μλ§λ μ΄κ²μ μ€μ λ‘ form-data ν¨ν€μ§μ λ²κ·Έμ λκΉ?
λμΌν λ¬Έμ κ° μμ΅λλ€. base64 λ¬Έμμ΄μ΄ μκ³ νμΌλ‘ 보λ΄μΌ ν©λλ€. λ΄ base64λ₯Ό λ²νΌλ‘ λ³νν λ€μ @philipp-spiessμ²λΌ μ½κΈ° μ€νΈλ¦ΌμΌλ‘ λννμ§λ§ μλνμ§ μμ΅λλ€. ν΄κ²° λ°©λ²μ μ°ΎμΌμ ¨λμ?
μ λ°μ΄νΈ: νμ¬ ν΄κ²° λ°©λ²μ streams2λ₯Ό μ¬μ©νλ bhttp(https://www.npmjs.com/package/bhttp)λ₯Ό μ¬μ©νλ κ²μ λλ€.
λ²νΌλ₯Ό μ§μ μ¬μ©νμ¬ νμΌμ μ λ‘λν μ μμμ΅λλ€. νμΌ κ΄λ ¨ μ 보(νμΌ μ΄λ¦, μ ν, ...)λ₯Ό μ§μ νκΈ°λ§ νλ©΄ λ©λλ€.
var formData = {
'file': {
value: buffer,
options: {
filename: file.filename,
contentType: file.mimetype
}
}
}
https://github.com/form-data/form-data#alternative -submission-methods
@PierreCavalet , μ΄ λ°©λ²μ μλνμ§λ§ λΆννλ μλνμ§ μμμ΅λλ€.
λ΄ "ν΄κ²° λ°©λ²"μ λ¨μν request
λΌμ΄λΈλ¬λ¦¬λ₯Ό μ¬μ©νμ§ μκ³ nodejs http μλΉμ€λ₯Ό μ¬μ©νμ¬ λ€μ€ λΆλΆ POSTλ₯Ό ꡬννλ κ²μ
λλ€.
@PierreCavalet λ²νΌκ° μ΄λ―Έ μΈμ½λ©λ ν μ€νΈμ λκΉ? λμκ² λ²νΌλ μμ²μ μΈμ½λ©μ κΉ¨λ¨λ¦° λ°μ΄λ리 λΈλ‘μΌλ‘ λ°μν©λλ€(λΆλͺ ν μ λλ‘ μΈμ½λ©λμ§ μμκΈ° λλ¬Έμ).
νΈμ§: λΆλͺ ν νΉλ³ν μΈμ½λ©μ΄ νμνμ§ μμ΅λλ€. λ¨μ§ μλͺ»λ λΉνΈ μ€νμ μΌ μλ μμ΅λλ€! μ΄μ¨λ λλ μ€λ₯κ° μλͺ»λ λ°μ΄νΈμ λν΄ λΆννλ μλ²μλ€λ κ²μ κΈ°μ΅ν©λλ€.
@philipp-spiess λ΄ λ²νΌλ λ€μμΌλ‘ μμ±λ©λλ€.
Buffer.from(base64string, 'base64')
μ, λ°μ΄λ리 λΈλ‘μ λλ€. μ€λͺ μμλ μ£Όμ΄μ§ JavaScript λ¬Έμμ΄μ ν¬ν¨νλ μ λ²νΌλ₯Ό μμ±νλ€κ³ λμ μμ΅λλ€. μ 곡λ κ²½μ° μΈμ½λ© 맀κ°λ³μλ λ¬Έμμ΄μ λ¬Έμ μΈμ½λ©μ μλ³ν©λλ€.
@PierreCavalet λ΄κ° μ¬μ©νκ³ μλ Buffer
express
νμΌ μ
λ‘λ λ―Έλ€μ¨μ΄ multer
μμ λ°λ‘ κ°μ Έμμ΅λλ€.
@philipp-spies μ΄μνλ€μ. λ΄ base64 λ¬Έμμ΄μ λ²νΌμ base64 μΈμ½λ©μμ κ°μ Έμ€κ³ μ΄ λ²νΌλ λ΄ νμΌ μ λ‘λμμ λ°λ‘ κ°μ Έμ΅λλ€. (μΈμ½λ©μ λ€λ₯Έ μλΉμ€μμ μννλ―λ‘ "μ무κ²λ"μ λν΄ "μΈμ½λ© λ° λμ½λ©"ν©λλ€. λ°λΌμ κ·Έκ²μ λΉμ μκ²λ ν¨κ³Όκ° μμ΄μΌ ν©λλ€.
@samkelly bhttp μ¬μ© μ μΆμ²ν΄ μ£Όμ μ κ°μ¬ν©λλ€. κ·Έκ²μ μλ²½νκ² μλν©λλ€!
@ bchr02 μ!
μ΄ μ€λ₯ μΆμ : form-data μ _length_retriever ν¨μμ λ¬Έμ κ° μλ κ²μΌλ‘ νλͺ
λμμ΅λλ€. 3κ°μ μμ ν μ΄ν΄λ μ€νΈλ¦Ό(κΈ°λ³Έμ μΌλ‘ fd
νλκ° μλ νμΌ, HTTP μλ΅ λλ μμ² μΆλ ₯ μ€νΈλ¦Ό) μ€ νλκ° μλ μ€νΈλ¦Όμ΄ μλ κ²½μ° κΈ°λ³Έμ μΌλ‘ μ΄λ₯Ό μννλ €λ©΄ μμ λ°μ΄ν°μ κ±°μ§λ§μ ν΄μΌ ν©λλ€. μ¬λ°λ₯Έ κ²(κ·Έλ¦¬κ³ μ€νΈλ¦Όμ μ νν λ°μ΄νΈ κΈΈμ΄κ° νμν¨). μλμν€λ €λ©΄ λ€μκ³Ό κ°μ΄ νμ΅λλ€.
var buffer = Buffer.from(base64string, 'base64');
buffer['httpVersion'] = true;
buffer.headers = { 'content-length': 64 }
var formData = {
'file': {
value: buffer,
options: {
filename: file.filename,
contentType: file.mimetype
}
}
}
λ§€μ° μ€μν©λλ€. options
μ filename
νλλ₯Ό μ§μ ν΄μΌ ν©λλ€. κ·Έλ μ§ μμΌλ©΄ λ€λ₯Έ μμΈκ° λ°μν©λλ€.
νμΌ μ΅μ
μ μ§μ ν μ μλ κ²½μ° νμΌ μ€νΈλ¦Όμ λ°μ΄νΈ κΈΈμ΄λ‘ options.knownLength
λ₯Ό μ§μ ν μ μμ΄μΌ νλ©° FormDataμμ μ νν©λλ€.
μ€μ λ‘ λ§μ΄ 곡κ°λμ§λ μμμ§λ§ FormDataμ μΆκ° μ 보 μ μΈκΈλμ΄ μμ΅λλ€. λ΄κ° λ§ν μμλ μ§κΈκΉμ§ μμ²μ μ΄λμλ μΈκΈνμ§ μμ΅λλ€.
μ, ν¨κ³Όκ° μμμ΅λλ€. μλ²½ 2μμ λλ²κΉ μ νλλ‘ κ°λ₯΄μ³ μ£ΌμΈμ. λλ knownLengthλ₯Ό μλνμ§λ§ μμΈκ° λ°μνλ€κ³ λ§ΉμΈν μ μμ§λ§, νμΌ μ΄λ¦ νλκ° λΆμ‘±νμ¬ νΌλμ΄ λ°μνμ μ μμ΅λλ€.
μ΄κ²μ gzip μ€νΈλ¦Όμ μΌλΆμΈ κ²μ μ λ‘λνκ³ μμΌλ―λ‘ κΈΈμ΄λ₯Ό λͺ¨λ₯΄κΈ° λλ¬Έμ λ΄ μν©μμλ μλνμ§ μμ΅λλ€.
@ sam0x17 μ€μ λ‘ λ΄κ° λ§ν μμλ ν requestλ νμ¬ transfer-encoding: chunked
μ§μνμ§ μμΌλ―λ‘ bhttpλ₯Ό μ¬μ©νμ§ μμ΅λλ€.
λν보μμμ€
νμ
λμΌν λ¬Έμ μ μ§λ©΄νμ΅λλ€. μ¬κΈ°μ μ§μ http λͺ¨λμ μ¬μ©νλ ν΄κ²° λ°©λ²μ΄ μμ΅λλ€.
const streamSample = fs.createReadStream('data.csv').pipe(passThrough);
const formHTTP = new FormData();
formHTTP.append('sampleFieldText', 'text-sample');
formHTTP.append('myFile', streamSample);
const requestToSend = http.request({
method: 'post',
host: 'localhost',
path: '/http',
headers: formHTTP.getHeaders()
});
formHTTP.pipe(requestToSend);
requestToSend.on('response', (res) => {
console.log('HTTP response', res.statusCode);
});
requestToSend.on('error', (e) => {
console.log('ERROR HTTP', e);
});
@BenjD90
ν΄κ²° λ°©λ²μ μ¬μ©νμ§λ§ μ€νΈλ¦Όμ΄ μ ν μ μ‘λμ§ μλ κ² κ°μ΅λλ€. κ΄λ ¨μ±μ΄ μλ κ²½μ° μμ μΈ‘μμ multerλ₯Ό μ¬μ©νκ³ μμ΅λλ€.
@Ncifra νμ¬ νλ‘μ νΈμμ λ§€μΌ μ¬μ©νκΈ° λλ¬Έμ ν΄κ²° λ°©λ²μ΄ ν¨κ³Όκ° μλ€κ³ νμ ν©λλ€.
https://beeceptor.com/μμ μ€νΈλ¦Όμ ν
μ€νΈν μ μμ΅λλ€. ;)
λλ μ€μ λ‘ μ΄κ²μ λ€μκ³Ό κ°μ΄ ν΄κ²°νμ΅λλ€. https://github.com/form-data/form-data/issues/356#issue -234978025
λ¬Έμ μ κ΄λ ¨λ λ΄ μλ λ¬Έμ λ λ€μκ³Ό κ°μ΅λλ€. https://github.com/form-data/form-data/issues/409
@BenjD90 νμ¬ μμ μ€μΈ νλ‘μ νΈμμ λ§€μ° μ§μ°λ κΈ°λ₯μ΄μκΈ° λλ¬Έμ μ½λλ₯Ό λλλ Έκ³ ν μ€νΈν μ μμ΅λλ€. λͺ¨λ ν μ€νΈκ° λ무 λ§μ ν¬μ μ½λλ₯Ό μμ±νκΈ° λλ¬Έμ λ΄κ° λκ°λ₯Ό λμΉκ³ μμμ μλ μμ΅λλ€. κ·Έλλ μμ²μ κΈ°λ‘νκ³ μμ λ°μ΄ν° κ°μ²΄μ νμΌμ΄ μλ κ² κ°μμ§λ§ λ€λ₯Έ λΉ λ°μ΄λ리 λ°μ΄ν°κ° μ¬λ°λ₯΄κ² μ μ‘λλ λμ multerλ νμΌμ λ°μ§ λͺ»ν κ² κ°μ΅λλ€.
μ΄ λ¬Έμ λ μ΅κ·Ό νλμ΄ μμκΈ° λλ¬Έμ μλμΌλ‘ μ€λλ κ²μΌλ‘ νμλμμ΅λλ€. λ μ΄μ νλμ΄ μμΌλ©΄ νμλ©λλ€. κ·νμ κΈ°μ¬μ κ°μ¬λ립λλ€.
@stale μ΄ λ²κ·Έλ κ°μ² μ‘΄μ¬μ΄λ©° λΉμΌ μμ λμ΄μΌ ν©λλ€^^
μ, λμνμ΅λλ€. κ·Έλλ§νΌ μ§κΈμ΄ μ€μν©λλ€. λλ κΈ°λ³Έμ μΌλ‘ bhttp
λμ request
λ₯Ό λ€μ μ¬μ©νκΈ° μ μ μ΄κ²μ΄ μμ λκΈ°λ₯Ό κΈ°λ€λ¦¬κ³ μμ΅λλ€. μ΄κ²μ streams λ° streams2 APIμ κΈ°λ³Έ κΈ°λ₯μ΄λ©° request
μμ μμ ν μ§μλμ΄μΌ ν©λλ€.
https://github.com/form-data/form-data/pull/397#issuecomment -471976669 λ° https://github.com/bitinn/node-fetch/pull/707#issuecomment -569850948μ μ°Έμ‘°νμΈμ.
κ°μ₯ μ μ©ν λκΈ
λ²νΌλ₯Ό μ§μ μ¬μ©νμ¬ νμΌμ μ λ‘λν μ μμμ΅λλ€. νμΌ κ΄λ ¨ μ 보(νμΌ μ΄λ¦, μ ν, ...)λ₯Ό μ§μ νκΈ°λ§ νλ©΄ λ©λλ€.
https://github.com/form-data/form-data#alternative -submission-methods