Request: Unggahan file hanya berfungsi dengan aliran baca standar

Dibuat pada 28 Des 2016  ·  26Komentar  ·  Sumber: request/request

Saya telah mencoba mengunggah file (menggunakan permintaan POST multi-bagian) yang ada di dalam arsip TAR (saya menggunakan perpustakaan tar-stream untuk mendapatkan aliran ke file tertentu di dalam arsip TAR). Tapi selalu gagal dengan kesalahan ECONNRESET. Setelah sedikit bereksperimen, sepertinya itu hanya dapat mengunggah aliran yang dibuat secara langsung dengan fs.createReadStream dan gagal dengan kesalahan yang tidak relevan untuk semua aliran lainnya.

Berikut adalah contoh minimal untuk mereproduksi masalah. Jika aliran PassThrough dilewatkan ke formData maka terjadi kesalahan berikut:

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' }

Server:

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);

Klien:

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 });
});

Komentar yang paling membantu

Saya telah berhasil mengunggah file saya menggunakan buffer secara langsung. Anda hanya perlu menentukan informasi terkait file (nama file, jenis, ...)

var formData = {
  'file': {
    value: buffer,
    options: {
      filename: file.filename,
      contentType: file.mimetype
    }
  }
}

https://github.com/form-data/form-data#alternative -submission-methods

Semua 26 komentar

Saya mengalami masalah yang sama ketika saya mencoba untuk membungkus Buffer dalam aliran baca untuk mengunggahnya sebagai permintaan multi-bagian yang valid.

Saya juga telah mencoba mencari cara untuk mengatasi masalah ini selama beberapa waktu dan mengalami masalah yang sama yang disebutkan di atas. Adakah yang menemukan solusi untuk ini? Mungkin ini sebenarnya bug dengan paket form-data?

Masalah yang sama di sini, saya memiliki string base64 dan saya harus mengirimkannya sebagai file. Saya mengonversi base64 saya menjadi buffer dan kemudian, seperti @philipp-spiess, saya membungkusnya dalam aliran baca, tetapi tidak berhasil. Apakah kalian menemukan pekerjaan di sekitar?

perbarui: untuk saat ini solusi saya menggunakan bhttp (https://www.npmjs.com/package/bhttp) yang menggunakan streams2

Saya telah berhasil mengunggah file saya menggunakan buffer secara langsung. Anda hanya perlu menentukan informasi terkait file (nama file, jenis, ...)

var formData = {
  'file': {
    value: buffer,
    options: {
      filename: file.filename,
      contentType: file.mimetype
    }
  }
}

https://github.com/form-data/form-data#alternative -submission-methods

@PierreCavalet , saya mencoba cara ini tetapi sayangnya tidak berhasil.

"Solusi" saya adalah tidak menggunakan perpustakaan request dan mengimplementasikan POST multi-bagian menggunakan layanan http nodejs.

@PierreCavalet Apakah buffer Anda sudah mengkodekan teks? Bagi saya buffer itu adalah gumpalan biner yang merusak penyandian permintaan (karena tampaknya tidak dikodekan dengan benar).

Sunting: Rupanya tidak diperlukan penyandian khusus, mungkin hanya sedikit offset yang salah ?! Bagaimanapun saya ingat bahwa kesalahannya adalah server mengeluh tentang byte yang tidak valid.

@philipp-spiess buffer saya dibuat dengan:

Buffer.from(base64string, 'base64')

Jadi ya itu adalah gumpalan biner. Dokumentasi mengatakan bahwa itu membuat Buffer baru yang berisi string JavaScript yang diberikan. Jika disediakan, parameter pengkodean mengidentifikasi pengkodean karakter string.

@PierreCavalet Buffer yang saya gunakan langsung dari multer , middleware pengunggahan file untuk express .

@philipp-spiess Ini aneh. String base64 saya berasal dari penyandian base64 buffer, dan buffer ini langsung dari unggahan file saya. (Pengkodean dilakukan oleh layanan lain, itu sebabnya kami "mengkodekan dan mendekode" untuk "tidak ada"). Jadi itu harus bekerja untuk Anda juga.

@samkelly terima kasih banyak atas rekomendasi Anda untuk menggunakan bhttp . Ini bekerja dengan sempurna!

@ bchr02 misalnya!

Melacak kesalahan ini: ternyata menjadi masalah dengan fungsi _length_retriever form-data . Jika Anda memiliki aliran yang bukan salah satu dari 3 aliran yang sepenuhnya dipahami (pada dasarnya file dengan bidang fd , respons HTTP, atau aliran keluaran permintaan), pada dasarnya Anda harus berbohong pada data formulir untuk melakukannya hal yang benar (dan Anda harus memiliki panjang byte aliran yang tepat). Untuk membuatnya berfungsi, saya akhirnya melakukan ini:

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
    }
  }
}

Sangat penting: Anda HARUS menentukan bidang filename di options , jika tidak, Anda mendapatkan pengecualian lain.

Jika Anda dapat menentukan opsi file, Anda harus dapat menentukan options.knownLength dengan panjang byte aliran file Anda dan itu akan diambil oleh FormData.

Itu disebutkan dalam readme FormData meskipun tidak banyak dipublikasikan. Permintaan tidak menyebutkannya di mana pun sekarang sejauh yang saya tahu.

Ah, itu berhasil: ajari saya melakukan debugging apa pun pada jam 2 pagi. Saya berani bersumpah saya mencoba knownLength dan mendapat pengecualian, tapi itu mungkin karena kurangnya bidang nama file yang menyebabkan kekacauan.

ini tidak berfungsi untuk situasi saya, karena saya mengunggah sesuatu yang merupakan bagian dari aliran gzip, oleh karena itu saya tidak tahu panjangnya.

@ sam0x17 Memang tidak, sejauh yang saya tahu, permintaan saat ini tidak mendukung transfer-encoding: chunked , jadi Anda menggunakan bhttp.

Lihat juga

tanda

Saya menghadapi masalah yang sama, inilah solusi saya, menggunakan modul http langsung.

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
Saya menggunakan solusi Anda, tetapi tampaknya aliran tidak terkirim sama sekali. Saya menggunakan multer di sisi penerima, jika ada relevansinya.

@Ncifra Saya yakin solusi saya berhasil, karena saya menggunakannya setiap hari di proyek saya saat ini.
Anda dapat menguji streaming Anda di https://beeceptor.com/ ;)

Saya benar-benar menyelesaikan ini dengan mengikuti: https://github.com/form-data/form-data/issues/356#issue -234978025
Ini masalah asli saya yang terkait dengan masalah: https://github.com/form-data/form-data/issues/409

@BenjD90 Saat ini saya mengembalikan kode dan tidak dapat mengujinya karena itu adalah fitur yang sangat tertunda pada proyek yang saya kerjakan. Mungkin saya melewatkan sesuatu karena semua pengujian itu telah membuat terlalu banyak kode yang jarang. Saya memang mencatat permintaan, dan objek form-data tampaknya memiliki file di dalamnya, tetapi multer tampaknya tidak menerimanya, sementara data non biner lainnya dikirim dengan benar.

Masalah ini secara otomatis ditandai sebagai basi karena tidak ada aktivitas terbaru. Ini akan ditutup jika tidak ada aktivitas lebih lanjut yang terjadi. Terima kasih atas kontribusi Anda.

@stale Bug ini ada dan harus diperbaiki pada hari itu ^^

Ya setuju, sekarang sama pentingnya dengan dulu. Saya pada dasarnya telah menunggu ini diperbaiki sebelum saya menggunakan request lagi daripada bhttp . Ini adalah fitur dasar dari streams dan streams2 API dan harus didukung sepenuhnya oleh request .

Apakah halaman ini membantu?
0 / 5 - 0 peringkat

Masalah terkait

IgorDePaula picture IgorDePaula  ·  3Komentar

jasonxia23 picture jasonxia23  ·  3Komentar

Kue
ghost picture ghost  ·  3Komentar

chenby picture chenby  ·  3Komentar

lupo9557 picture lupo9557  ·  3Komentar