Safari 在服务器端 refresh/onbeforeunload 上没有 运行 回调函数(调用客户端代码)
Safari does not run callback function on refresh/onbeforeunload on server side (calls client side code)
我正在尝试在卸载 window 时(即刷新页面时)向数据库发送一些请求。出于某种原因,仅在 Safari 上,客户端代码得到执行,但对服务器的请求永远不会通过。当我在调试器中手动单步执行代码时,服务器确实收到了请求并对其进行了很好的处理。
有人知道为什么会这样吗?
window.onbeforeunload = function() {
console.log("inside on before unload");
var requestParam = new a.ListRequest();
requestParam.setAction('set_delete');
var callback = function(isSuccess, response) {
if (isSuccess) {
//do something
} else {
// do something else
}
};
// Sends request to server
a.Fetch.list(requestParam, callback);
}
很可能在 Fetch 调用中发生的请求是异步的,Safari 没有等待它完成就转到下一个 page/closing 选项卡。如果您可以使调用同步,它应该可以工作。请记住,在某些工具中通常不鼓励和弃用同步调用。
这个与Jquery相关的回答对同步调用有很好的解释:
您可以使用 Beacon API
(FF、Chrome、Opera):
window.addEventListener('unload', logData, false);
function logData() {
navigator.sendBeacon("/log", analyticsData);
}
用户代理通常会忽略卸载处理程序中的异步 XMLHttpRequests
。为了解决这个问题,分析和诊断代码通常会在 unload
或 beforeunload
处理程序中进行同步 XMLHttpRequest
以提交数据。同步 XMLHttpRequest
强制用户代理延迟卸载文档,并使下一次导航看起来更慢。下一页无法避免这种页面加载性能不佳的感觉。
使用 sendBeacon()
方法,数据将在用户代理有机会这样做时异步传输到 Web 服务器,而不会延迟卸载或影响下一次导航的性能。
您可以使用 jQuery.ajax 将异步 属性 设置为 false async:false
window.onbeforeunload = function() {
$.ajax({
// Query to server
async:false,
method: "GET",
url: "your.page",
data: { param1 : "value1" }
}).done(function(jqXHR, textStatus) {
// Verify good data
// Do stuff
alert( "Request done: " + textStatus );
}).fail(function( jqXHR, textStatus ) {
alert( "Request failed: " + textStatus );
});
}
正如@craigts 所说,浏览器在 ajax 调用返回之前就已经消失了。
您可能会在该页面上多停留几秒钟。
window.onbeforeunload = function(e) {
return 'Dialog text here.';
};
但是,您的用户会觉得这很烦人。
第二个选项,寻找另一个事件而不是等待页面卸载。持续捕获您的数据。在更改时捕获它。用户会使用 link 继续吗?如果是这样,您可以使用 cancelEvent() 劫持 link,然后在 ajax 返回后继续。
我正在尝试在卸载 window 时(即刷新页面时)向数据库发送一些请求。出于某种原因,仅在 Safari 上,客户端代码得到执行,但对服务器的请求永远不会通过。当我在调试器中手动单步执行代码时,服务器确实收到了请求并对其进行了很好的处理。
有人知道为什么会这样吗?
window.onbeforeunload = function() {
console.log("inside on before unload");
var requestParam = new a.ListRequest();
requestParam.setAction('set_delete');
var callback = function(isSuccess, response) {
if (isSuccess) {
//do something
} else {
// do something else
}
};
// Sends request to server
a.Fetch.list(requestParam, callback);
}
很可能在 Fetch 调用中发生的请求是异步的,Safari 没有等待它完成就转到下一个 page/closing 选项卡。如果您可以使调用同步,它应该可以工作。请记住,在某些工具中通常不鼓励和弃用同步调用。
这个与Jquery相关的回答对同步调用有很好的解释:
您可以使用 Beacon API
(FF、Chrome、Opera):
window.addEventListener('unload', logData, false);
function logData() {
navigator.sendBeacon("/log", analyticsData);
}
用户代理通常会忽略卸载处理程序中的异步 XMLHttpRequests
。为了解决这个问题,分析和诊断代码通常会在 unload
或 beforeunload
处理程序中进行同步 XMLHttpRequest
以提交数据。同步 XMLHttpRequest
强制用户代理延迟卸载文档,并使下一次导航看起来更慢。下一页无法避免这种页面加载性能不佳的感觉。
使用 sendBeacon()
方法,数据将在用户代理有机会这样做时异步传输到 Web 服务器,而不会延迟卸载或影响下一次导航的性能。
您可以使用 jQuery.ajax 将异步 属性 设置为 false async:false
window.onbeforeunload = function() {
$.ajax({
// Query to server
async:false,
method: "GET",
url: "your.page",
data: { param1 : "value1" }
}).done(function(jqXHR, textStatus) {
// Verify good data
// Do stuff
alert( "Request done: " + textStatus );
}).fail(function( jqXHR, textStatus ) {
alert( "Request failed: " + textStatus );
});
}
正如@craigts 所说,浏览器在 ajax 调用返回之前就已经消失了。 您可能会在该页面上多停留几秒钟。
window.onbeforeunload = function(e) {
return 'Dialog text here.';
};
但是,您的用户会觉得这很烦人。
第二个选项,寻找另一个事件而不是等待页面卸载。持续捕获您的数据。在更改时捕获它。用户会使用 link 继续吗?如果是这样,您可以使用 cancelEvent() 劫持 link,然后在 ajax 返回后继续。