【问题标题】:Cancel File Upload Post request using Axios使用 Axios 取消 File Upload Post 请求
【发布时间】:2019-03-07 19:59:33
【问题描述】:

我正在尝试实现取消功能以在视频上传时取消视频的文件上传。这是我的前端在视频上传时的样子

这是我使用 axios 发布请求的代码:

export function processPost (body, callback, errorUpdate) {
// config for post
var config = {
  timeout: 300000,
  headers: { 'content-type': 'multipart/form-data' }

}

// url for server endpoint
var url = 'http://localhost:5000/uploader'

// actual post
axios
  .post(url, body, config)
  .then(callback)
  .catch(function (error) {
    // Non 200 Response
    if (error.response) {
      errorUpdate('non 200 response from server')
      // Request made but no response received
    } else if (error.request) {
      errorUpdate('no response from server')
      // something else happened
    } else {
      errorUpdate('Something Else Happened')
    }
    throw error
  })
}

这是前端的代码:

export default class Welcome extends React.Component {
  constructor (props) {
    super(props)
    this.state = {
      state: 'PENDING',
      selectedFile: null
    }
    this.handleClick = this.handleClick.bind(this)
    this.post = this.post.bind(this)
  }

  handleClick () {
    if (this.state.state === 'PENDING') {
      this.refs.fileUploader.click()
    } else {
      cancelPost()
      this.setState({ state: 'PENDING' })
    }
  }

  handleChange (selectorFiles) {
    if (selectorFiles.length === 0) return
    console.log(selectorFiles)
    this.post(selectorFiles[0])
  }

  post (file) {
    // set screen to loading
    this.setState({
      state: 'PROCESSING',
      selectedFile: file
    })

    // set up body
    const data = new FormData()
    data.append('file', file)

    // pass in header, body, then callback
    processPost(data,
      resp => {
        console.log(resp.data)
        this.props.successfulPost(file, URL.createObjectURL(file), resp.data.boardTranscription, resp.data.audioTranscription)
      },
      error => {
        // if there is an error, log it and reset state
        console.log(error)
        this.setState({ state: 'PENDING' })
      })
  }

  render () {
    var jumboClass = classNames({
      'jumbotron col-8 offset-2 light-pink text-center': true,
      'jumboProcessing': this.state.state === 'PROCESSING'
    })

    var input
    var loading
    if (this.state.state === 'PROCESSING') {
      input = null
      loading = (
        <div>
          <div className="spinner-border" role="status">
            <span className="sr-only">Loading...</span>
          </div>
          <p>processing {this.state.selectedFile.name} ...</p>
          <button className={'btn btn-outline-light'} onClick={this.handleChange('')}>Cancel</button>
        </div>
      )
    } else {
      input = (
        <React.Fragment>
          <br></br>
          <button
            className={'btn-light btn-lg'}
            onClick={this.handleClick}
          >Upload Video</button>
          <input id="file" ref="fileUploader" type="file" accept='video/*'
            style={{ display: 'none' }}
            onChange={ (e) => this.handleChange(e.target.files) } />
        </React.Fragment>
      )
      loading = null
    }
    return (
      <div className={'row vertical-center'}>
        <div className={jumboClass}>
          <h2 className={'h2 font-size:10vw'}>Welcome to AutoNote!</h2>
          <h6 className={'h6 font-size:5vw'}>Upload a video to generate a linked transcription.</h6>
          {input}
          <br></br>
          {loading}
        </div>
      </div>)
  }
}

Welcome.propsType = {
  successfulPost: PropTypes.function
}

我将如何在 Axios 中实现取消功能,以便当用户单击“取消”按钮时,发布请求将被取消?任何帮助深表感谢。谢谢!

【问题讨论】:

    标签: javascript reactjs axios cancel-button


    【解决方案1】:

    你需要使用CancelToken。

    基本上,在使用axios.post时,需要在config对象中传递一个canceltoken,当你想取消时,你可以调用取消函数。

    例子:

    let cancelTokenSource = axios.CancelToken.source();
    

    然后,在请求配置对象中,将令牌作为cancelToken 传递 说:

    config = { ...otherConfigs, cancelToken : cancelTokenSource.token }
    

    所以现在,我们可以使用

     cancelTokenSource.cancel('Upload cancelled');
    

    点击某个取消按钮即可取消您想说的任何地方。

    【讨论】:

    • 我可能做错了,但 Axios 似乎忽略了我对 cancelTokenSource.cancel() 的调用
    【解决方案2】:

    我认为应该这样做:

    您首先必须创建一个取消令牌,如下所示,并将其添加到您的 axios 发布请求之前

    const CancelToken = axios.CancelToken;
    const source = CancelToken.source();
    

    然后将cancelToken: source.token 添加到您的 axios 配置中

    var config = {
        /* ... */
        cancelToken: source.token,
    }
    

    现在你必须将source 存储在一个状态中,所以把它放在你的 axios 帖子之后

    this.setState({source});
    

    最后创建一个handleCancel() 方法并在用户点击取消按钮时调用它

    handleCancel() {
        this.state.source.cancel()
    }
    

    【讨论】:

      【解决方案3】:

      从axios 版本0.22.0 开始,您应该使用所谓的AbortController 来实现所需的行为,因为CancelToken 已被弃用。

      const controller = new AbortController();
      
      axios.get('/foo/bar', {
         signal: controller.signal
      });
      
      // cancel the request
      controller.abort();
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2019-12-19
        • 2017-10-14
        • 2017-06-30
        • 2020-12-04
        • 1970-01-01
        • 2018-06-23
        • 1970-01-01
        • 2018-06-23
        相关资源
        最近更新 更多