如何在页面卸载时可靠地跨域和跨浏览器发送请求

发布于 2024-08-29 01:39:53 字数 776 浏览 8 评论 0原文

我有由第三方加载的 JavaScript 代码。 javascript 跟踪许多指标,当用户退出页面时,我想将指标发送回我的服务器。

由于某些浏览器(例如 IE)中存在 XSS 检查,我无法执行简单的 jquery.ajax() 调用。相反,我使用 jquery 将图像 src 附加到页面。下面是代码,以浏览器为例:

    function record_metrics() {
        //Arbitrary code execution here to set test_url
        $esajquery('#MainDiv').append("<img src='" + test_url + "' />");
    }

    if ($esajquery.browser.msie) {
        window.onbeforeunload = function() { record_metrics(); }
    } else {
        $esajquery(window).unload(
            function(){ record_metrics(); }
        );
    }

如果我使用 window.onbeforeunload,FF 会中止对“test_url”的请求,并且 IE8 无法使用 jquery 的 unload()。如果任意 test_url 设置代码太长,IE8 也会无法工作,尽管如果立即附加到 DOM,IE8 似乎可以正常工作。

有没有更好的方法来解决这个问题?不幸的是,这确实需要在用户离开页面时执行。

I have javascript code that's loaded by 3rd parties. The javascript keeps track of a number of metrics, and when a user exits the page I'd like to send the metrics back to my server.

Due to XSS checks in some browsers, like IE, I cannot do a simple jquery.ajax() call. Instead, I'm appending an image src to the page with jquery. Here's the code, cased by browser:

    function record_metrics() {
        //Arbitrary code execution here to set test_url
        $esajquery('#MainDiv').append("<img src='" + test_url + "' />");
    }

    if ($esajquery.browser.msie) {
        window.onbeforeunload = function() { record_metrics(); }
    } else {
        $esajquery(window).unload(
            function(){ record_metrics(); }
        );
    }

FF aborts the request to "test_url" if I use window.onbeforeunload, and IE8 doesn't work with jquery's unload(). IE8 also fails to work if the arbitrary test_url setting code is too long, although IE8 seems to work fine if the is immediately appended to the DOM.

Is there a better way to solve this issue? Unfortunately this really needs to execute when a user leaves the page.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

巷雨优美回忆 2024-09-05 01:39:53

为了后人的缘故,这就是我最终要做的事情:

if ($.browser.msie) {
    window.onbeforeunload = function() { $('#div1').append("<img src='record_call' />");   
} else {
    $(window).unload(
        if ($.browser.webkit) {
           $.ajax(url:record_call, async:false);
        } else {
           $('#div1').append("<script src='record_call' />");
        }
    );
}

我发现 IE 可以附加一个 img,但不能附加一个脚本,可能是因为脚本占用更多资源,并且在尝试加载它之前会被切断。对于 webkit,附加脚本有时有效,但附加图像似乎永远不起作用。最后,我默认使用该脚本(主要针对 FF),因为较旧的浏览器版本似乎都可以很好地使用它。由于 xss,IE 会阻止 webkit 使用的 AJAX 调用。

另外,IE从来不支持jquery的unload函数,而其他浏览器也不支持onbeforeunload,所以这些都必须加大小写。这当然不是一个完美的解决方案,但它在大多数情况下都有效。

For posterity's sake, here's what I ended up doing:

if ($.browser.msie) {
    window.onbeforeunload = function() { $('#div1').append("<img src='record_call' />");   
} else {
    $(window).unload(
        if ($.browser.webkit) {
           $.ajax(url:record_call, async:false);
        } else {
           $('#div1').append("<script src='record_call' />");
        }
    );
}

I found that IE works appending an img, but not a script, possibly because the script is more resource intensive and it cuts out before trying to load it. For webkit, appending a script sometimes works, but appending an image never seemed to work. Lastly, I default to the script (mainly for FF) because older browser versions all seem to play well with it. IE blocks the AJAX call used by webkit because of xss.

In addition, IE never works with jquery's unload function, and the other browsers don't work with onbeforeunload, so those have to be cased. This certainly isn't a pretty solution, but it works most of the time.

调妓 2024-09-05 01:39:53

对于那些尝试使用上面的 Agmin 方法的人来说,请注意:当您使用 jQuery 的 append() 方法附加脚本标记时,内部 jQuery 连接使用 jQuery.ajax()执行脚本,因此如果您附加的脚本标签位于不同的域中,同源策略将阻止脚本执行。

A heads up for those trying to use Agmin's method above: When you use jQuery's append() method to append a script tag, the internal jQuery wiring uses jQuery.ajax() to execute the script, so if the script tag you're appending is on a different domain, Same Origin Policy will prevent the script from being executed.

初心未许 2024-09-05 01:39:53

据我所知,某些浏览器只接受 onbeforeunload 结果的文本字符串。尝试更像这样的事情:

jQuery(window).bind('beforeunload', function() { record_metrics(); return ''; } );

不确定,但这甚至可能适用于所有浏览器,但我目前只是猜测。

ps 另请参阅 我该如何覆盖 OnBeforeUnload 对话框并将其替换为我自己的对话框?

From what I remember, some browsers only accept a text string for the onbeforeunload result. Try something more like this:

jQuery(window).bind('beforeunload', function() { record_metrics(); return ''; } );

Not sure, but that might even work for all browsers, but I'm only guessing at this point.

p.s. also see How can I override the OnBeforeUnload dialog and replace it with my own?

街角卖回忆 2024-09-05 01:39:53

你应该看看 easyXDM 库

http://easyxdm.net/

我认为它会让你的工作变得轻松同源策略设置的限制

You should take a look at easyXDM library

http://easyxdm.net/

I think it will make your work easy regarding the limitation set in place by the Same Origin Policy

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文