我正在编写一个应用程序来修改服务器中缓存对象的数据。修改是通过ajax调用执行的,该调用基本上更新了该对象的属性。当用户完成工作后,我有一个基本的“保存更改”按钮,允许他们保存数据并刷新缓存的对象。
为了保护用户,我想警告他们,如果他们没有保存的话,在对服务器对象进行修改时尝试离开页面。因此,我创建了一个名为IsInitialized的Web服务方法,该方法将根据是否已保存更改返回true或false。如果它们尚未保存,我想提示用户并让他们有机会取消导航请求。
这是我的问题 - 虽然我的调用工作正常,但我似乎无法通过ajax成功调用来设置其回调函数的变量值。这是我现在的代码。
////Catches the users to keep them from navigation off the page w/o saved changes...
window.onbeforeunload = CheckSaveStatus;
var IsInitialized;
function CheckSaveStatus() {
var temp = $.ajax({
type: "POST",
url: "URL.asmx/CheckIfInstanceIsInitilized",
data: "{}",
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function(result) {
IsInitialized = result.d;
},
error: function(xmlHttpRequest, status, err) {
alert(xmlHttpRequest.statusText + " " + xmlHttpRequest.status + " : " + xmlHttpRequest.responseText);
}
});
if (IsInitialized) {
return "You currently have unprocessed changes for this Simulation.";
}
}
我觉得我可能会尝试以不恰当的方式使用Success回调。如何在Success回调上设置javascript变量,以便我可以决定是否应该提示用户未保存的更改消息?
正如刚刚指出的那样,我正在进行异步调用,这意味着在我的方法返回之前调用其余的代码。有没有办法使用该ajax调用,但仍然捕获window.onunload事件? (不进行同步ajax)
答案 0 :(得分:35)
由于您在卸载事件中需要此行为,因此您必须进行同步调用。但是,它可能会冻结浏览器窗口/选项卡,具体取决于调用将花费多长时间,但因为您有效地试图阻止用户关闭窗口...
将async: false
添加到您的JSON以进行同步通话。
答案 1 :(得分:7)
jquery页面的一个例子:
var html = $.ajax({
url: "some.php",
async: false
}).responseText;
答案 2 :(得分:4)
问题是Ajax调用的请求是异步的。因此,当您检查IsInitialized时,呼叫尚未完成。
我建议在成功函数中指定您的行为。
基本上使用ajax进行同步调用即使不是不可能,也不是真的不鼓励。
答案 3 :(得分:2)
理论上你可以杀死事件(返回false)并在成功时关闭窗口,但我认为你会遇到一些用户设置的Javascript限制,并且只是混淆了他们的窗口没有关闭的原因。所以,我同意Pawel Krakowiak,ajax调用本身必须是同步的。
我要补充一点,你要给用户一些关于你正在检查状态的通知(请不要弹出窗口,请在窗口顶部找到一个好的通知横幅),并确保设置$ .ajax“timeout”选项对于这种情况更合理,所以他们不会永远等待窗口关闭。
答案 4 :(得分:2)
尝试通过ajax请求的成功回调设置数据对象的属性时遇到了类似的问题。使用async: false
也无法解决我的问题。我最终做的是在ajax调用之外使用setTimeout
调用,并将超时值设置为1,如下所示:
function getSessionid() {
$.ajax({
type: 'POST',
url: 'getSession.php',
dataType: 'text',
success: function(result){myData.sessionid = result;},
error: function(data) {alert("Error!\n" + data);}
});
setTimeout(function() {alert('sessionid = ' + myData.sessionid);},1);
}
只有1毫秒的延迟才能让世界变得与众不同。没有它,sessionid
属性不会在ajax调用之外设置,尽管回调中的警报显示它确实被设置了。如果你遇到类似的问题,可以考虑一下。
答案 5 :(得分:1)
对我来说,最好的方法是在我的ajax调用上使用async:false选项。虽然我理解Rashack对此做的犹豫不决,但我认为这种情况证明了手段的合理性。
Jerph也非常关注确保在我尝试验证其状态时不会让用户挂起。加上超时选项很重要。
感谢所有评论的人。
答案 6 :(得分:0)