当用户关闭浏览器时执行Flex清理功能

3

我有一个Flex客户端应用程序。当用户关闭浏览器时,我需要一个清理函数在Flex中运行。我在网上找到了以下解决方案,但它只对我起到了一半的作用。我该如何修复它呢?提前感谢任何回复!

症状

  • CustomEvent被触发,但未执行。
    >> CustomEvent.SEND_EVENTS的事件处理程序由Mate EventMap定义。所有处理程序只是调用一个HTTPServiceInvoker。在调试控制台中,我能够看到处理程序和HTTPServiceInvoker被触发,但既没有调用resultHandlers也没有调用faultHandlers。我知道这个事件处理程序没有问题,因为当我在按钮单击处理程序中分派相同的CustomEvent.SEND_EVENTS时,它的行为与我预期的完全相同)
  • 浏览器似乎在关闭之前等待cleanUp函数完成。(所有跟踪都在浏览器关闭之前打印出来了)

代码

我将以下内容添加到index.template.html中:

window.onbeforeunload = clean_up;

function clean_up()
{
 var flex = document.${application} || window.${application};
 flex.cleanUp();
}

在应用程序的MXML文件中使用以下内容:

import flash.external.ExternalInterface;

public function init():void {
ExternalInterface.addCallback("cleanUp",cleanUp);
}

public function cleanUp():void {   

   var newEvent:CustomEvent = new CustomEvent(CustomEvent.SEND_EVENTS);
   newEvent.requestObj = myFormModel;

   dispatchEvent(newEvent);

   // for testing purposes
   // to see whether the browser waits for Flex cleanup to finish before closing down   
   var i:int;
   for (i=0; i<10000; i++){
        trace(i);
   }    

}

我的设置

  • FlexBuilder 3
  • Mate MVC框架(Mate_08_9.swc)
  • FlashPlayer 10
3个回答

2
很遗憾,没有一种可靠的方法可以异步执行这样的清理功能。HTTPService的result/fault事件在cleanUp方法返回后异步发生。浏览器只等待onbeforeunload函数(js中的clean_up函数)返回。除非您从该函数调用event.preventDefault(),否则页面将被关闭。请注意,调用preventDefault()将导致一个确定/取消弹出窗口询问:

您确定要离开此页面吗?

单击“确定”继续,单击“取消”留在当前页面。

如果用户选择“确定”,浏览器仍将关闭。您可以使用event.returnValue属性向弹出窗口添加自定义消息。

//tested only in Firefox
window.addEventListener("beforeunload", onUnload, false);
function onUnload(e)
{
   e.returnValue = "Some text that you want inserted between " +
     "'Are you sure' and 'Press OK' lines";
   e.preventDefault();
}

所以,无法确保清理完成,因为无法阻止用户选择“确定”吗? - tomato

1

清理客户端会话的另一种方法是使用JavaScript和as3中的external.interface类。以下是示例代码:

JavaScript:

function cleanUp()
{

    var process;
    var swfID="customRightClick";
    if(navigator.appName.indexOf("Microsoft") != -1){
        process = window[swfID];
        }else
    {
        process = document[swfID];
    }
    process.cleanUp();
}

在定义清理函数的as3类中使用以下代码:

import flash.external.ExternalInterface;

if (ExternalInterface.available)
{
    ExternalInterface.addCallback("cleanUp", cleanUp);
}

function cleanUp():void {// your code }

这是一种很好的在客户端清理会话的方式。谢谢。:) 不幸的是,它不适用于我的情况,因为我正在尝试通过HTTP请求在服务器端触发某些操作,当用户关闭浏览器时。我可以这样做,但我问题的关键仍然是如何确保我的HTTP请求在浏览器关闭之前已经完成。 - tomato

1

你永远无法100%可靠地检测浏览器代码。如果你真的需要运行操作,那么最安全的做法是让客户端向服务器发送“我还活着”的消息。服务器需要按客户端跟踪时间,并在指定时间内(留有一些余地)未收到消息的客户端上运行清理活动。

时间越长越好,这取决于清理的时间关键性。如果你可以等待5分钟,那就太好了,否则请考虑1分钟或30秒或者你的应用程序所需的任何时间。


谢谢你的回答。这是一个不同的解决问题的方法,我会记在心里的... - tomato

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接