使用Axios取消文件上传发布请求

guz6ccqo  于 2023-02-12  发布在  iOS
关注(0)|答案(3)|浏览(474)

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

下面是我使用axios编写post请求的代码:

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中实现取消功能,以便用户单击“取消”按钮时,发布请求将被取消?任何帮助都将不胜感激。谢谢!

mefy6pfw

mefy6pfw1#

更新:CancelToken已弃用。根据axios cancellation docs,从v0.22.0开始Axios支持AbortController以API方式取消请求:

const controller = new AbortController();

// Example: axios.post(url, data, config)
axios.post('/foo/bar', {}, {
   signal: controller.signal
});

// cancel the request
controller.abort()

注意:以下代码已弃用,适用于v0.22.0之前的Axios版本

您首先必须创建一个cancel标记,如下所示,并将其添加到axios post请求之前

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

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

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

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

this.setState({source});

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

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

cpjpxq1n2#

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

const controller = new AbortController();

axios.get('/foo/bar', {
   signal: controller.signal
});

// cancel the request
controller.abort();
pzfprimi

pzfprimi3#

您需要使用CancelToken
基本上,当使用axios.post时,您需要在配置对象中传递一个canceltoken,当您想要取消时,您可以调用cancel函数。
示例:

let cancelTokenSource = axios.CancelToken.source();

然后,在request config对象中,将令牌作为cancelToken传递,例如:

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

所以现在我们可以用

cancelTokenSource.cancel('Upload cancelled');

取消任何你想说的,在点击一些取消按钮。

相关问题