7

我正在尝试在卸载页面之前向服务器发布一个帖子,我遵循了这个并且它工作正常。我的问题是 window.unload 上的 $.post 在卸载触发。我尝试使用注销链接并检查我的日志,我得到以下信息:

Started GET "/signout" for 127.0.0.1 at 2012-11-22 00:15:08 +0800
Processing by SessionsController#destroy as HTML
Redirected to http://localhost:3000/
Completed 302 Found in 1ms


Started GET "/" for 127.0.0.1 at 2012-11-22 00:15:08 +0800
Processing by HomeController#index as HTML
  Rendered home/index.html.erb within layouts/application (0.4ms)
  Rendered layouts/_messages.html.erb (0.1ms)
Completed 200 OK in 13ms (Views: 12.9ms)


Started POST "/unloading" for 127.0.0.1 at 2012-11-22 00:15:08 +0800
Processing by HomeController#unloading as */*
  Parameters: {"p1"=>"1"}
WARNING: Can't verify CSRF token authenticity
Completed 500 Internal Server Error in 0ms

NoMethodError (undefined method `id' for nil:NilClass):
  app/controllers/home_controller.rb:43:in `unloading'

第一部分是注销,然后用户被重定向到 root,然后它运行帖子('/unloading')。

有没有办法让“/卸载”先执行然后执行卸载操作?

我有这个作为我的 jquery 帖子

$(window).unload ->
  $.ajax {
    async: false,
    beforeSend: (xhr) ->
      xhr.setRequestHeader('X-CSRF-Token', $('meta[name="csrf-token"]').attr('content'))
    , url: '/unloading'
    , type: 'Post'
    , data: {
      p1: '1'
    }
  }

更新

所以我确实将 ajax 请求转移到 beforeunload 并且它正在工作,但我必须做一个return null来删除出现的对话框,因为如果我不这样做,ajax 仍然会在弹出对话框时触发(即使没有回答“是/否我想离开这个页面”)。结果是这样的:

window.onbeforeunload ->
  $.ajax {
    async: false,
    beforeSend: (xhr) ->
      xhr.setRequestHeader('X-CSRF-Token', $('meta[name="csrf-token"]').attr('content'))
    , url: '/unloading'
    , type: 'Post'
    , data: {
      p1: '1'
    }
  }
  return null

另外,我现在只用 Chrome 尝试过它,它按预期工作。尚未尝试在其他浏览器上。

4

3 回答 3

9

试试beforeUnload活动

卸载事件的确切处理因浏览器版本而异。例如,某些版本的 Firefox 会在点击链接时触发该事件,但不会在窗口关闭时触发。在实际使用中,应该在所有支持的浏览器上测试行为,并与专有的 beforeunload 事件进行对比。

更新

当页面卸载时触发 unload 事件。

更新 2

要禁用Are you sure that you want to leave this page?弹出窗口,请尝试nullbeforeUnload回调函数返回

更新 3

检查跨浏览器兼容性

于 2012-12-20T02:49:26.363 回答
4

正如@NickKnudson 建议的那样,在卸载窗口之前使用“beforeUnload”事件回发表单数据:

window.onbeforeunload = function() {
  $.ajax {
    async: false,
    beforeSend: (xhr) ->
      xhr.setRequestHeader('X-CSRF-Token', $('meta[name="csrf-token"]').attr('content'))
    , url: '/unloading'
    , type: 'Post'
    , data: {
      p1: '1'
    }
  }
}

大约两周前遇到了完全相同的情况,切换到 beforeUnload 解决了问题。

于 2012-12-20T16:38:19.070 回答
3

问题是窗口的unload事件在关闭窗口之前不会等待 AJAX 调用(这是异步的)完成。此外,jQuery 似乎没有对beforeunload事件进行内置处理——这就是为什么您需要恢复为原生 JS 代码来处理它的原因。见下文:

注:用CoffeeScript编写)

window.onbeforeunload = function() {
    $.ajax {
        async: false, // Important - this makes this a blocking call
        beforeSend: (xhr) ->
            xhr.setRequestHeader('X-CSRF-Token', $('meta[name="csrf-token"]').attr('content'))
      , url: '/unloading'
      , type: 'Post'
      , data: {
            p1: '1'
        }
    }
};

onbeforeunload - 卸载页面时在卸载事件之前触发的事件。

另请参阅有关此主题的Google 论坛讨论。

于 2012-12-21T09:17:15.113 回答