带有 axios 的进度条
Progress Bar with axios
我必须使用进度条显示文件的上传状态。我正在使用 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);
我该如何解决这个问题?
我找到了答案。事件的名称是 onUploadProgress
,我使用的是 progress
我认为问题出在 "progress" 事件本身,正如您在 Axios configuration 中看到的那样,它本身不支持进度。相反,你应该听 onUploadProgress 或 onDownloadProgress
另一个问题是获取 totalLength,我尝试通过以下方式进行操作:查看 lengthComputable,如果不是,则尝试从 header 获取长度,如果不是,则尝试获取解压缩的内容长度(如上次所示) resort) 那么你应该可以用这个值做任何你想做的事。
这不是一个万无一失的实现!只要 totalLength 不可用,它就会失败。
为了让它更稳固一点,您可以使用 setInterval 实现 "fake" 进度,每秒手动增加进度。解决承诺后,手动将进度设置为 100%。如果你使用 CSS 转换实现它,你应该得到一个平滑的解决方案,即使进度并不总是 "correct"
如果您需要更多代码,我制作了一个类似的加载程序 (GitHub link)。
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 ));
}
});
这是一个非常方便的库,无需太多编码即可实现此目的 - https://github.com/rikmms/progress-bar-4-axios/
之前,我用 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>
)
}
}
我必须使用进度条显示文件的上传状态。我正在使用 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);
我该如何解决这个问题?
我找到了答案。事件的名称是 onUploadProgress
,我使用的是 progress
我认为问题出在 "progress" 事件本身,正如您在 Axios configuration 中看到的那样,它本身不支持进度。相反,你应该听 onUploadProgress 或 onDownloadProgress
另一个问题是获取 totalLength,我尝试通过以下方式进行操作:查看 lengthComputable,如果不是,则尝试从 header 获取长度,如果不是,则尝试获取解压缩的内容长度(如上次所示) resort) 那么你应该可以用这个值做任何你想做的事。
这不是一个万无一失的实现!只要 totalLength 不可用,它就会失败。
为了让它更稳固一点,您可以使用 setInterval 实现 "fake" 进度,每秒手动增加进度。解决承诺后,手动将进度设置为 100%。如果你使用 CSS 转换实现它,你应该得到一个平滑的解决方案,即使进度并不总是 "correct"
如果您需要更多代码,我制作了一个类似的加载程序 (GitHub link)。
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 ));
}
});
这是一个非常方便的库,无需太多编码即可实现此目的 - https://github.com/rikmms/progress-bar-4-axios/
之前,我用 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>
)
}
}