Axios: событие onUploadProgress запускается только после полной загрузки видео

#javascript #reactjs #axios #httprequest

#javascript #reactjs #axios #httprequest

Вопрос:

Я пытаюсь отслеживать ход загрузки видео и, соответственно, отображать его пользователю.
Это запрос axios, который загружает видео.

   const config = {
    onUploadProgress: function (progressEvent) {
      var percentCompleted = Math.round(
        (progressEvent.loaded * 100) / progressEvent.total
      );
      console.group("profileActions.uploadProfileVideoURL");
      console.log("progressEvent.loaded: ", progressEvent.loaded);
      console.log("progressEvent.total: ", progressEvent.total);
      console.log("percentCompleted: ", percentCompleted);
      console.groupEnd();
    },
  };

  axios
    .post("/api/profile/uploadProfileVideoURL", videoData, config)
 

Проблема в том, что оно запускается только при полной загрузке видео.
Я обнаружил, что это обсуждалось в этом выпуске Github Axios:

Только 100% может быть запущено, если ваши загружаемые файлы слишком малы или скорость загрузки / выгрузки слишком высока. Возможно, попробуйте загрузить файл размером 10 МБ.

Итак, я попытался загрузить видео размером 100 МБ, и событие все равно запускается в конце загрузки.
Есть идеи, почему это происходит?
И могу ли я точно настроить axios, чтобы событие запускалось при определенных значениях прогресса?

Ответ №1:

В ваш код необходимо добавить FormData и некоторые заголовки, например (MIME-тип файла) для запроса. Вы можете использовать эту логику:

Сначала создайте служебную функцию для обработки загрузки с прогрессом, как показано ниже:

 import axios from "axios";

const Upload = (files, customHeader, cbProgress, cb) => {
  const config = {
    onUploadProgress: function (progressEvent) {
      var percentCompleted = Math.round(
        (progressEvent.loaded * 100) / progressEvent.total
      );
      cbProgress(percentCompleted);
      console.log(percentCompleted);
    },
    headers: {
      ...customHeader,
      // "Content-Type": files[0].type,
      // "Content-Type": "multipart/form-data",
    },
  };

  let data = new FormData();
  data.append(<field_name>, files[0]); // Name of the field for uploading

  console.log({ ...customHeader });

  axios
    .post(<url>, data, config)
    .then((res) => cb(res))
    .catch((err) => console.log(err));
};

export default Upload;
 

Краткое описание приведенного выше кода:

  • customHeader : передайте любые заголовки в конфигурацию, например: "Content-Type", "Authorization", etc...
  • cbProgress : Это обратный вызов, когда функция вызывается и выполняется.
  • cb : Это обратный вызов, когда вызывается функция и загрузка завершена.

Примечание: FormData , Используется для отправки файла, и вы должны его использовать.

Интерфейс FormData предоставляет способ легко создать набор пар ключ / значение, представляющих поля формы и их значения, которые затем можно легко отправить с помощью метода XMLHttpRequest.send() . Он использует тот же формат, что и форма, если бы для типа кодировки было задано значение «multipart / form-data».

Наконец, вы можете вызвать эту служебную функцию в любом месте, где захотите, как показано ниже:

 const customHeader = {
    "Content-Type": files[0] amp;amp; files[0].type, // This is an example
    "Content-Type": "multipart/form-data", // This is an example
  };

  Upload(
    files,
    customHeader,
    (percent) => {
      // ...
    },
    (res) => {
      // ...
    }
  );