: ERR_EMPTY_RESPONSE через две минуты ожидания -ax ios -post - nodejs - PullRequest
1 голос
/ 24 апреля 2020

Я пытаюсь сделать загрузку файла в приложении nodejs / реагировать. Загрузка файла работает хорошо, но у меня есть некоторые проблемы, когда я хочу получить ответ на мой запрос await.post(). Когда я загружаю файл, я сделал счетчик, чтобы показать, что файл загружается, и я хочу, чтобы этот счетчик остановился, когда загрузка закончилась sh, а затем отобразил сообщение, информирующее пользователя, что загрузка завершена sh .

Я объясняю проблемы, потому что это немного сложно.

Когда я работаю локально:

Через две минуты (я понял это по времени) консоль моего браузера отображает сообщение об ошибке net::ERR_EMPTY_RESPONSE. Но на стороне сервера все продолжается и запрос завершается без помех. Но с передней стороны мой счетчик никогда не прекращает вращаться, даже когда запрос завершен, и когда мой почтовый запрос отправляет сообщение res на мою клиентскую сторону.

Я думал, что это время ожидания моего сервера, поэтому я ' мы сделали много тестов, поместив setTimeout на мой сервер:

var server = app.listen(PORT, () =>
  console.log(`Server started on port ${PORT}`)
);

server.timeout = 3840000;

А также в моем запросе маршрута:

router.post('/', async (req, res) => {
  req.setTimeout(3600000);

И даже я пытаюсь изменить время ожидания моего axios.post функция на стороне клиента:

const res = await axios.post('/api/students', newFile, {
      timeout: 3600000,
    });

Но с моей проблемой ничего не решается.

И что странно, что когда приложение размещается, проблема в другом!

На самом деле нет сообщения об ошибке, но через 1 минуту спиннер останавливается без причины.

Я провел много исследований, но ничего не решило мою проблему, вот уже несколько дней я нахожусь на ней и не понимаю почему. Я подумал, может быть, это проблема с прокси-сервером или тайм-аут браузера, но я не знаю ...

Если у вас даже небольшое преимущество, это может мне очень помочь! Спасибо за помощь!

ОБНОВЛЕНИЕ:

Код моего / api / студенческого маршрута

      const express = require('express');
const router = express.Router();
const fileUpload = require('express-fileupload');
const Student = require('../../models/Student');
const CSVToJSON = require('csvtojson');
const utf8 = require('utf8');
var accents = require('remove-accents');

const NodeGeocoder = require('node-geocoder');
const sleep = require('util').promisify(setTimeout);

let msg = 'Etudiants ajoutés à la base de données';

//The column that we want to keep in the database
const goodColumn = [
  'Civilite',
  'Nom_patronymique',
  'Prenom',
  'Date_naissance',
  'No_etudiant',
  'Libelle_nationalite',
  'Telephone_portable',
  'Mailum',
  'Adresse_fixe_postal',
  'Adresse_fixe_ville',
  'Libelle_etape',
];

// Set up the environnement for geocoding the adress
const options = {
  provider: 'openstreetmap',
};

const geoCoder = NodeGeocoder(options);

//FUNCTION TO VERIFY IF A STRING HAS A NUMBER IN IT
function hasNumber(myString) {
  return /\d/.test(myString);
}

router.post('/', (req, res, next) => {
  // This should be BEFORE `fileUpload`
  req.setTimeout(0);
  next();
});

router.use(fileUpload());

//@route   POST api/students
//@desc    Fill the database with the json information
//@access  Public
router.post('/', async (req, res, next) => {
  //FORMER FILES ROUTES
  //take the information
  const buf = Buffer.from(req.files.file.data).toString();

  //CONVERSION CSV STRING TO JSON
  CSVToJSON()
    .fromString(buf)
    .then((source) => {
      for (let i = 0; i < source.length; i++) {
        for (let j = 0; j < Object.keys(source[i]).length; j++) {
          const columnName = Object.keys(source[i]);
          columnName.forEach((element) => {
            if (!goodColumn.includes(element)) {
              delete source[i][element];
            }
            if (element == 'Libelle_etape') {
              const str = source[i]['Libelle_etape'];
              const result = accents.remove(utf8.decode(str));
              source[i]['Libelle_etape'] = result;
            }
          });
        }
      }
      data = JSON.stringify(source);
      datajson = JSON.parse(data);
      //USE THE FUNCTION TO PUT THE DATA IN THE DB
      insertIntoDataBase(datajson);
    });

  // CLEAR TABLE BEFORE ADD NEW STUDENTS FROM FILE
  Student.deleteMany({}, function (err) {});

  //ROUTES STUDENTS - FUNCTION  TO PUT THE JSON DATA IN THE DATABASE
  async function insertIntoDataBase(jsonString) {
    for (let i = 0; i < jsonString.length; i++) {
      console.log(`boucle ${i}`);

      try {
        //READ DATA FROM DE CSV FILE (already convert into json data) AND PUT IT INTO VARIABLES
        let {
          Civilite,
          Nom_patronymique,
          Prenom,
          Date_naissance,
          No_etudiant,
          Libelle_nationalite,
          Telephone_portable,
          Mailum,
          Adresse_fixe_postal,
          Adresse_fixe_ville,
          Libelle_etape,
        } = jsonString[i];
        console.log(Nom_patronymique + ' ' + Prenom);

        // VERIFICATION VILLE STRING FORMAT ( AVOIR NUMBER OR ..EME)
        if (hasNumber(Adresse_fixe_ville)) {
          Adresse_fixe_ville = Adresse_fixe_ville.replace(/[0-9]/g, '');
          if (Adresse_fixe_ville.endsWith(' EME')) {
            Adresse_fixe_ville = Adresse_fixe_ville.substring(
              0,
              Adresse_fixe_ville.length - 4
            );
          }
        }

        //VERIFICATION OF THE PHONE NUMBER - if empty attributes a default value
        if (Telephone_portable !== undefined && Telephone_portable.length < 1) {
          Telephone_portable = '0000000000';
        }

        // GEOCODING THE ADDRESS TO CONVERT INTO LATITUDE AND LONGITUDE

        geoCoder
          .geocode({
            city: Adresse_fixe_ville,
            zipcode: Adresse_fixe_postal,
          })
          .then(async (res) => {
            //TEST

            var Latitude;
            var Longitude;
            if (res[0] !== undefined) {
              Latitude = res[0].latitude;
              Longitude = res[0].longitude;
            } else {
              console.log(Adresse_fixe_ville);
              Latitude = 0.0;
              Longitude = 0.0;
            }

            //CREATE A STUDENT WITH THE INFO + LAT AND LONG
            student = new Student({
              Civilite,
              Nom_patronymique,
              Prenom,
              Date_naissance,
              No_etudiant,
              Libelle_nationalite,
              Telephone_portable,
              Mailum,
              Adresse_fixe_postal,
              Adresse_fixe_ville,
              Libelle_etape,
              Latitude,
              Longitude,
            });
            //VERIFICATION IF ALL THE ATTRIBUTE OF THE STUDENT ARE OK - IF NOT : undefined
            if (
              !(
                student.Civilite === undefined ||
                student.Nom_patronymique === undefined ||
                student.Prenom === undefined ||
                student.Date_naissance === undefined ||
                student.No_etudiant === undefined ||
                student.Libelle_nationalite === undefined ||
                student.Telephone_portable === undefined ||
                student.Mailum === undefined ||
                student.Adresse_fixe_postal === undefined ||
                student.Adresse_fixe_ville === undefined ||
                student.Libelle_etape === undefined
              )
            ) {
              //SAVE THE STUDENT IN THE DATABASE
              await student.save();
            } else {
              res.status(500);
              msg =
                'Le fichier csv téléchargé est au mauvais format de données';
            }
          })
          .catch((err) => {
            console.log(err);
          });
      } catch (err) {
        console.log(err.message);
        res.status(500);
        msg =
          'Erreur serveur, veuillez réessayer avec un fichier csv au bon format';
        return;
      }

      //WAIT FOR GEOCODER - 1,2 second
      await sleep(1200);
    }
    //COUNT A MANY STUDENT WE HAVE IN THE DATABASE
    Student.find().exec(function (err, results) {
      var count = results.length;
      res.json({ msg: msg, count: count });
    });
  }
});

//@route   GET api/students
//@desc    Return all the students in the database (all information / attributes)
//@access  Public
router.get('/', function (req, res, next) {
  Student.find(function (err, students) {
    if (err) {
      res.send(err);
    }
    res.json(students);
  });
});

module.exports = router;

1 Ответ

0 голосов
/ 24 апреля 2020

В узле < 13.0.0 время ожидания сокета по умолчанию составляет 2 минуты, поэтому через две минуты сокет будет закрыт, и вы получите ERR_EMPTY_RESPONSE на стороне клиента, так как сокет был закрыт, не позволяя вам ответить на это. request.

С узла 13.0.0 время ожидания по умолчанию было установлено на 0 (без времени ожидания), и, возможно, это причина того, что он работает при развертывании приложения, возможно, на вашем сервере запущен узел >= 13.0.0.

Если после использования req.setTimeout со значением, превышающим 2 минуты, и у вас все еще есть эта проблема, это может быть вызвано тем, что вы неправильно завершили запрос или вы использовали req.setTimeout неправильно place.

Это огромный файл, это CSV с 1300 лини, загрузка занимает примерно 30 минут

Из вашего комментария я могу сказать, что req.setTimeout ваш маршрут не делает то, что вы хотите, потому что до этого у вас есть промежуточное ПО, вероятно multer от просмотра в вашем коде, который не устанавливает req.setTimeout на >30 min.

требование Есть время ожидания, прежде чем оно достигнет вашего маршрута. Вы должны сделать что-то вроде этого:

app.post(
    '/', 
    (req, res, next) => {
        // Set request setTimeout BEFORE any other middlewares
        req.setTimeout(ms('35m')); // using `ms` package
        next();
    },
    upload.single('file'), // or whatever multer setup you have
    (req, res, next) => {
        // Your route

    }
)

С этим кодом у вас есть 35 минут, чтобы загрузить и завершить свой ответ, так как он не истечет время ожидания в промежуточном программном обеспечении multer через 2 минуты. Конечно, если вы не знаете, сколько времени это займет, скорее всего, вы можете использовать req.setTimeout(0) или любое другое значение, которое вы считаете подходящим.


Обновление

Для вашего кода вам нужно будет сделать следующее:

// or router.use((req, res, next) => ...)
router.post('/', (req, res, next) => {
   // This should be BEFORE `fileUpload`
   req.setTimeout(0);
   next();
});

router.use(fileUpload());

//@route   POST api/students
//@desc    Fill the database with the json information
//@access  Public
router.post('/', async (req, res, next) => {
   // ...rest of your code
})
...