[英]How to abort pending jquery ajax request when user navigates to other page?
I have defined a method to send jquery ajax request like this 我已经定义了一个发送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);
}
});
}
From the place of calling I keep the reference of ajax call 从调用的地方我保留了ajax调用的引用
this.ajaxRequest = sendAjaxRequest(Url, data);
and based on user navigation if user navigates away from page ( goes to another page on same website via router ) I want to cancel any pending ajax request. 并且基于用户导航,如果用户导航离开页面(通过路由器转到同一网站上的另一个页面)我想取消任何待处理的ajax请求。
From the docs I found that jquery jqXHR
object has an abort
method to cancel any ajax request. 从文档中我发现jquery
jqXHR
对象有一个abort
方法来取消任何ajax请求。 But in my ajaxRequest
object I don't have any such method available. 但是在我的
ajaxRequest
对象中,我没有任何这样的方法可用。 I am using jquery 2.2 . 我正在使用jquery 2.2 。
For clarification I also want to add that I am using react , and want to achieve this. 为了澄清我还想补充说我正在使用反应 ,并希望实现这一目标。
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();
},
Taken from this link . 取自此链接 。
They basically say that When fetching data asynchronously, use componentWillUnmount to cancel any outstanding requests before the component is unmounted. 他们基本上说当异步获取数据时,使用componentWillUnmount在卸载组件之前取消任何未完成的请求。
I must be doing something wrong. 我一定做错了什么。 Any help is appreciated.
任何帮助表示赞赏。
According to the ajax documentation , you're doing it properly. 根据ajax文档 ,你正确地做到了。 The
$.ajax()
function returns an object that has an abort
function. $.ajax()
函数返回一个具有abort
函数的对象。 You should check for existence of the function because it might not exist if the request has already finished. 您应该检查函数是否存在,因为如果请求已经完成,它可能不存在。
componentWillUnmount: function(){
if (this.ajaxRequest && this.ajaxRequest.abort){
this.ajaxRequest.abort()
}
}
http://api.jquery.com/jquery.ajax/#jqXHR http://api.jquery.com/jquery.ajax/#jqXHR
Please don't try to abort the AJAX request in this case. 在这种情况下,请不要尝试中止AJAX请求。 The better way is not to do anything if the component is unmounted .
如果卸载组件 ,更好的方法是不做任何事情 。 Take a look at this:
看看这个:
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
});
},
In the big picture, not just Ajax requests but any async operation inside a component that may change the component's states should be register in componentDidMount
and unregister in componentWillUnmount
, or else you'll find yourself get lost async spaghetti mess. 在大画面,而不仅仅是Ajax请求,但一个组件内的任何异步操作可能更改组件的状态应在注册
componentDidMount
和注销 componentWillUnmount
,否则你会发现自己迷路了异步意大利面条一塌糊涂。
In the above example, I used this._requestSuccess = ...;
在上面的例子中,我使用了
this._requestSuccess = ...;
to register and this._requestSuccess = () => {};
注册和
this._requestSuccess = () => {};
to unregister the handler, but in real world application, you'll see people use Flux or Redux to do the same thing. 取消注册处理程序,但在现实世界的应用程序中,你会看到人们使用Flux或Redux做同样的事情。
I highly encourage you to use one of those to manage your application data flow rather than just sending and aborting ajax requests everywhere. 我强烈建议您使用其中一个来管理您的应用程序数据流,而不是仅仅在每个地方发送和中止Ajax请求。
Just have a look on the fiddle . 只要看看小提琴 。 Run the fiddle and check the network tab.
运行小提琴并检查网络选项卡。
$('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>
The ajax variable will hold all the ajax related functions as shown in the documentation . ajax变量将保存所有与ajax相关的函数,如文档中所示。
If componentWillUnmount
is not called have a look at your router configuration. 如果未调用
componentWillUnmount
,请查看您的路由器配置。
<Route path="/" component={App}>
<IndexRoute component={Home}/>
<Route path="invoices/:invoiceId" component={Invoice}/>
<Route path="accounts/:accountId" component={Account}/>
</Route>
In this example the {App}
component is never unmounted since it's at the root. 在此示例中,
{App}
组件永远不会卸载,因为它位于根目录。 When you navigate from /invoices/
to /invoices/123
the Invoices component is not unmounted either. 当您从
/invoices/
导航到/invoices/123
,也不会卸载Invoices组件。
Alternatively you can also tie in to the routers setRouteLeaveHook
like this 或者你也可以像这样绑定到路由器
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
became available in react-router 2.4.0 withRoute
在react-router 2.4.0中可用
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.