繁体   English   中英

当用户导航到其他页面时,如何中止挂起的jquery ajax请求?

[英]How to abort pending jquery ajax request when user navigates to other page?

我已经定义了一个发送jquery ajax请求的方法

sendAjaxRequest(URL, data) {
    return $.ajax({
        type        : 'POST',
        url         : URL,
        crossDomain : true,
        data        : JSON.stringify(data),
        dataType    : 'json'
    }).fail((responseData) => {
        if (responseData.responseCode) {
            console.error(responseData.responseCode);
        }
    });
}

从调用的地方我保留了ajax调用的引用

this.ajaxRequest = sendAjaxRequest(Url, data);

并且基于用户导航,如果用户导航离开页面(通过路由器转到同一网站上的另一个页面)我想取消任何待处理的ajax请求。

从文档中我发现jquery jqXHR对象有一个abort方法来取消任何ajax请求。 但是在我的ajaxRequest对象中,我没有任何这样的方法可用。 我正在使用jquery 2.2

为了澄清我还想补充说我正在使用反应 ,并希望实现这一目标。

  componentDidMount: function() {
    this.serverRequest = $.get(this.props.source, function (result) {
      var lastGist = result[0];
      this.setState({
        username: lastGist.owner.login,
        lastGistUrl: lastGist.html_url
      });
    }.bind(this));
  },

  componentWillUnmount: function() {
    this.serverRequest.abort();
  },

取自此链接

他们基本上说当异步获取数据时,使用componentWillUnmount在卸载组件之前取消任何未完成的请求。

我一定做错了什么。 任何帮助表示赞赏。

根据ajax文档 ,你正确地做到了。 $.ajax()函数返回一个具有abort函数的对象。 您应该检查函数是否存在,因为如果请求已经完成,它可能不存在。

componentWillUnmount: function(){
  if (this.ajaxRequest && this.ajaxRequest.abort){
    this.ajaxRequest.abort()
  }
}

http://api.jquery.com/jquery.ajax/#jqXHR

在这种情况下,请不要尝试中止AJAX请求。 如果卸载组件 ,更好的方法是不做任何事情 看看这个:

componentDidMount: function() {
  // Register to the handler
  this._requestSuccess = this.requestSuccess.bind(this); 
  $.get(this.props.source, this.requestSuccess);
},

componentWillUnmount: function() {
  // "Unregister" by assign it to an empty function
  this._requestSuccess = () => {};
 },

requestSuccess(lastGist) {
  // Do your work
  this.setState({
    username: lastGist.owner.login,
    lastGistUrl: lastGist.html_url
  });
},

在大画面,而不仅仅是Ajax请求,但一个组件内的任何异步操作可能更改组件的状态应在注册 componentDidMount注销 componentWillUnmount ,否则你会发现自己迷路了异步意大利面条一塌糊涂。

在上面的例子中,我使用了this._requestSuccess = ...; 注册和this._requestSuccess = () => {}; 取消注册处理程序,但在现实世界的应用程序中,你会看到人们使用FluxRedux做同样的事情。

我强烈建议您使用其中一个来管理您的应用程序数据流,而不是仅仅在每个地方发送和中止Ajax请求。

只要看看小提琴 运行小提琴并检查网络选项卡。

 $('button').on('click', function() { var _ajax = $.ajax({ type: 'POST', url: "yourURL", crossDomain: true, data: JSON.stringify('hello'), dataType: 'json' }).fail((responseData) => { if (responseData.responseCode) { console.error(responseData.responseCode); } }); _ajax.abort(); }); 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.0/jquery.min.js"></script> <button> Click me </button> 

ajax变量将保存所有与ajax相关的函数,如文档中所示。

如果未调用componentWillUnmount ,请查看您的路由器配置。

<Route path="/" component={App}>
  <IndexRoute component={Home}/>
  <Route path="invoices/:invoiceId" component={Invoice}/>
  <Route path="accounts/:accountId" component={Account}/>
</Route>

在此示例中, {App}组件永远不会卸载,因为它位于根目录。 当您从/invoices/导航到/invoices/123 ,也不会卸载Invoices组件。

或者你也可以像这样绑定到路由器setRouteLeaveHook

import React from 'react';
import { withRouter } from 'react-router';

const MyComponent = React.creatClass({

  componentDidMount() {
    this.request = $.get( /* ... */ );

    this.props.router.setRouteLeaveHook(this.props.route, (request) => {
      request.abort();
      return true;
    });
  }

/* .... */

});


export default withRouter(MyComponent);

withRoute在react-router 2.4.0中可用

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM