带有 axios 的进度条

问题描述 投票:0回答:4

我必须使用进度栏显示文件的上传状态。我正在使用

axios
发出 http 请求。我按照他们的 github 页面上的示例https://github.com/mzabriskie/axios/blob/master/examples/upload/index.html

我的代码如下所示:

this.store().then(() => {
    var form = new FormData();
        form.append('video', this.file);
        form.append('uid', this.uid);

        axios.post('/upload', form, {
            progress: (progressEvent) => {
                    if (progressEvent.lengthComputable) {
                       console.log(progressEvent.loaded + ' ' + progressEvent.total);
                       this.updateProgressBarValue(progressEvent);
                    }
           }
       })                   
});

但是,它根本不执行

console.log(progressEvent.loaded + ' ' + progressEvent.total);
,也不调用
this.updateProgressBarValue(progressEvent);

我该如何解决这个问题?

javascript progress-bar vuejs2 axios
4个回答
53
投票

我认为问题在于“进度”事件本身,正如您可以在Axios配置中读到的那样,进度本身不受支持。相反,你应该听 onUploadProgressonDownloadProgress

另一个问题是获取totalLength,我尝试按照以下方式进行操作:查看lengthComputable,如果不是,则尝试从标头获取长度,如果不尝试获取解压缩的内容长度(作为最后的手段),那么您应该能够用价值做任何你想做的事。

这不是一个万无一失的实现!只要总长度不可用,它就会失败。

为了使其更加可靠,您可以使用 setInterval 每秒手动增加进度来实现“假”进度。一旦承诺得到解决,手动将进度设置为 100%。如果你使用 CSS 过渡来实现它,即使进度并不总是“正确”,你也应该得到一个顺利的解决方案

如果您需要更多代码,我制作了一个类似的加载器(GitHub 链接)。

onUploadProgress: (progressEvent) => {
    const totalLength = progressEvent.lengthComputable ? progressEvent.total : progressEvent.target.getResponseHeader('content-length') || progressEvent.target.getResponseHeader('x-decompressed-content-length');
    console.log("onUploadProgress", totalLength);
    if (totalLength !== null) {
        this.updateProgressBarValue(Math.round((progressEvent.loaded * 100) / totalLength));
    }
});

44
投票

我找到了答案。活动名称是

onUploadProgress
,我使用的是
progress


4
投票

这是一个非常方便的库,无需太多编码即可实现此目的 - https://github.com/rikmms/progress-bar-4-axios/


4
投票

之前,我使用 onUploadProgress 事件制作进度条。

这是我的示例代码,如下所示。

import React from 'react';
import Progress from 'react-progressbar';
import axios from 'axios';
export default class App extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      progress: 0,
      uploadFile: null,
    }
  }
  onChangeFile = (event) => {
    this.setState({ uploadFile: event.target.files[0] })
  }

  onUpload = () => {
    const config = {
      onUploadProgress: progressEvent => {
        let { progress } = this.state;
        progress = (progressEvent.loaded / progressEvent.total) * 100;
        this.setState({ progress });
      }
    }

    let formData = new FormData();
    formData.append("file", this.state.uploadFile);
    axios.post('http://your_backend_url/api/v1/upload', formData, config).then(res => {
      if (res.data.status == 200) {
        console.log("done: ", res.data.message);
      }
    }).catch(err => {
      console.log("error: ", err.message);
    })
  }

  render() {
    return (
      <div className="App">
        <Progress completed={this.state.progress} />
        <input type="file" onChange={this.onChangeFile} />
        <button onClick={this.onUpload.bind(this)} >File Upload</button>
      </div>
    )
  }
}
© www.soinside.com 2019 - 2024. All rights reserved.