【问题标题】:How to wait until file is uploaded using Axios如何等到使用 Axios 上传文件
【发布时间】:2020-06-01 07:02:17
【问题描述】:

我正在开发一个可以上传和下载文件的 Reactjs 项目。

但是当我上传文件时,来自 Axios 的 PUT 请求在文件完全上传到我的数据库之前完成。 我使用 Axios 的 onUploadProgress,点击上传按钮后它直接显示 100%,而文件尚未上传。

似乎只有在进度条达到100%时才开始背面文件的上传。 我不知道如何正确同步进度条和文件上传。

我的代码

正面

  onUpload() {
    const data = new FormData();
    for (var i = 0; i < this.state.selectedFile.length; i++) {
      data.append("file", this.state.selectedFile[i]);
    }
    axios
      .put("http://localhost:5000/api/files/upload", data, {
        onUploadProgress: ProgressEvent => {
          this.setState({
            loaded: Math.round(
              (ProgressEvent.loaded * 100) / ProgressEvent.total
            )
          });
        }
      })
      .then(res => {
        console.log("File(s) uploaded", res);
      });
  }

返回

export const uploadFile = (req, res) => {
  const myFile = (Array.isArray(req.files.file)
    ? req.files.file
    : [req.files.file]
  ).filter(e => e);
  // upload file(s) to directory
  for (let i = 0; i < myFile.length; i++) {
    myFile[i].mv("./src/uploads/" + myFile[i].name, function(err) {
      if (err) {
        return res.status(500).send(err);
      }
    });
    // save file(s) to database
    Upload.create({
      type: myFile[i].mimetype,
      name: myFile[i].name,
      data: myFile[i].data
    });
  }
  res.send("file uploaded !");
};

顺便说一句,我使用https://www.npmjs.com/package/express-fileupload 进行文件上传

编辑

  onUpload() {
    const data = new FormData();
    for (var i = 0; i < this.state.selectedFile.length; i++) {
      data.append("file", this.state.selectedFile[i]);
    }
    axios
      .post("http://localhost:5000/api/files/upload", data, {
        headers: {
          "Content-type": "multipart/form-data"
        },
        onUploadProgress: ProgressEvent => {
          this.setState({
            loaded: Math.round(
              (ProgressEvent.loaded * 100) / ProgressEvent.total
            )
          });
        }
      })
      .then(res => {
        console.log("File(s) uploaded", res);
      });
  }

【问题讨论】:

  • 有两件事对我来说似乎不正确,您使用的是不合适的 PUT 方法,因为您正在数据库中创建新条目(因此更喜欢使用 POST),并且您正在不通过 content-type header multipart/form-data (第二个是最重要的)尝试使用这个 content-type header
  • 没有办法从服务器到前端就进度进行通信,除非您想在每毫秒内进行一次服务器调用以了解进度。我建议您在 onUploadprogress 事件中将进度条设置为 95%,并在 .then 事件中完成承诺。
  • @MehdiBenmoha 对于一些测试我创建了上传按钮,通常这个代码由我的提交按钮调用,并且 multipart/form-data 在表单内。正如您在我的编辑中看到的那样,我更改了我的代码,但没有任何改变。
  • @SachinVishwakarma 我该怎么做?
  • 添加答案作为对您评论的回复。

标签: javascript reactjs file-upload axios


【解决方案1】:
onUpload() {
const data = new FormData();
for (var i = 0; i < this.state.selectedFile.length; i++) {
  data.append("file", this.state.selectedFile[i]);
}
axios
  .post("http://localhost:5000/api/files/upload", data, {
    headers: {
      "Content-type": "multipart/form-data"
    },
    onUploadProgress: ProgressEvent => {
      this.setState({
        loaded: 95
      });
    }
  })
  .then(res => {
   this.setState({
        loaded: 100
      });
    console.log("File(s) uploaded", res);
  });

}

【讨论】:

  • 我尝试了您的解决方案,但我的进度直接达到 100%。我认为我的帖子请求已发送,然后我的文件开始上传
  • 是的,这正是正在发生的事情......你需要欺骗前端或假设它会在平均 2-3 秒内完成并相应地显示进度
【解决方案2】:

您在访问 API 时就设置状态,这就是您在 API 访问时获得 100% 的原因。我建议你从服务器端传递"status = success""status = 201" 这样你就可以等待客户端的响应。即:-

onUpload() {
    const data = new FormData();
    for (var i = 0; i < this.state.selectedFile.length; i++) {
      data.append("file", this.state.selectedFile[i]);
    }
    axios
      .post("http://localhost:5000/api/files/upload", data, {
        headers: {
          "Content-type": "multipart/form-data"
        }
      })
      .then(res => {
        if(res.status === 'success') {
              onUploadProgress: ProgressEvent => {
               this.setState({
                 loaded: Math.round(
                (ProgressEvent.loaded * 100) / ProgressEvent.total
              )
           });
         }
        }
        console.log("File(s) uploaded", res);
      });
  }

【讨论】:

  • 语法或类似问题有问题:Expected an assignment or function call and instead saw an expression 在线 onUploadProgress: ProgressEvent =&gt;
  • 如果您删除保留 setState 的 'onUploadProgress: ProgressEvent => {}',那么您的代码将被编译,但我不确定它是否适合您。为了更好的说明,你能更新codesandbox上的代码吗?
  • 我正在尝试,但我必须更改代码以适应codesandbox。如果你愿意,我可以给你一个 github 仓库。
猜你喜欢
  • 2021-09-12
  • 2018-08-29
  • 2020-05-11
  • 2021-02-06
  • 2018-09-01
  • 1970-01-01
  • 1970-01-01
  • 2020-12-11
  • 1970-01-01
相关资源
最近更新 更多