Получение ERR_FS_FILE_TOO_LARGE при использовании отправки файла unirest с помощью put

Я использую unirest для загрузки такого файла

 unirest.put(fullUri)
    .auth({
      user: self.userName,
      pass: self.password
    })
    .header('X-Checksum-Sha1', sha1Hash)
    .header('X-Checksum-Md5', md5Hash)
    .send(fs.readFileSync(filePath))
    .end(function (response) {

Это отлично работает для небольших файлов, но для больших файлов я получаю ошибку ERR_FS_FILE_TOO_LARGE. Я уже пытался max_old_space_size безуспешно. Похоже, я могу исправить это, передав файл в потоковом режиме, но я не могу найти API для этого в библиотеке unirest js.


person parapura rajkumar    schedule 10.07.2020    source источник
comment
Каковы пределы вашей памяти? У вас достаточно оперативной памяти, чтобы загрузить весь файл в оперативную память?   -  person Tschallacka    schedule 13.07.2020
comment
Я знаю, что вы ищете ответ с помощью unirest, но unirest устарел. Вместо этого я рекомендую использовать axios.   -  person Devchris    schedule 19.07.2020


Ответы (3)


Похоже, это проблема с form-data из GitHub Issues


Получается, что юниресты используют form-data модуля NPM, а модуль form-data требует, чтобы если он получил поток, который не fs.ReadStream, нам нужно было предоставить информацию о файле по доп.

Пример:

form.append( 
  'my_file', 
  stream,
  {
    filename: 'bar.jpg', 
    contentType: 'image/jpeg', 
    knownLength: 19806,
  },
)

См.: https://github.com/form-data/form-data#void-append-string-field-mixed-value--mixed-options-

person Artistan    schedule 13.07.2020

Потоковая передача файлов с unirest доступна с помощью метода .attach:

 unirest.put(fullUri)
    .auth({
      user: self.userName,
      pass: self.password
    })
    .header('X-Checksum-Sha1', sha1Hash)
    .header('X-Checksum-Md5', md5Hash)
//    .send(fs.readFileSync(filePath))
    .attach('filename', fs.createReadStream(filePath))
    .end(function (response) {
person Avraham    schedule 14.07.2020
comment
Я уже пробовал это, и сервер не принимает это. Я думаю, это только для multipart/form-data - person parapura rajkumar; 14.07.2020
comment
Существует еще один способ потоковой передачи данных по HTTP с использованием Transfer-Encoding: chunked, который поддерживается пакетом request, но unirest, похоже, его не поддерживает. Ваш сервер вообще принимает какой-либо метод потоковой передачи? - person Avraham; 14.07.2020

Я не могу найти API для этого в библиотеке unirest js.

Это потому, что его нет: https://github.com/Kong/unirest-nodejs/issues/49:

  • #P3#

Вопрос все еще открыт.


Но из этой задачи и из исходный код вы можете узнать, что end() возвращает request (см. https://github.com/request/request)

Unirest.request = require('request')

...

  end: function (callback) {
    ...
    Request = Unirest.request($this.options, handleRequestResponse)
    Request.on('response', handleGZIPResponse)
    ...
    return Request
  }

и из исходного кода request вы можете узнать, что фактический запрос еще не отправлен (он отложен). Таким образом, вы можете взломать его. И вместо этого используйте его API:

const request = unirest.put(constants.server2)
  .auth({
    user: self.userName,
    pass: self.password
  })
  .header('X-Checksum-Sha1', sha1Hash)
  .header('X-Checksum-Md5', md5Hash)
  // .send(fs.readFileSync(filePath))
  .end(...)

fs.createReadStream(filePath).pipe(request) // just pipe it!

В качестве примечания: unirest основан на request, request — на устарело. Так что... возможно, вам стоит держаться подальше от unirest.

person x00    schedule 17.07.2020