【问题标题】:Call a POST request for logging from window unload调用 POST 请求以从窗口卸载进行日志记录
【发布时间】:2017-06-03 12:02:40
【问题描述】:

我一直在努力编写能够在关闭选项卡窗口时可靠地发出 POST 请求的代码。 Navigator.sendBeacon 似乎正是我所需要的(我只要求它适用于 Google Chrome)。

$(global).bind('unload', function () {
  let body = {
    UserEmail: appState.user.email,
    Job: {
      Id: appState.jobId
    },
    Timestamp: '/Date(' + new Date().getTime() + ')/',
    EventOrigin: 'PdfReviewClient',
    Event: 'JobClosed'
  };
  let headers = {
    Authorization: `JWT ${authenticationState.token}`,
    'Content-Type': 'application/json; charset=utf8'
  };
  let blob = new Blob([JSON.stringify(body)], headers);
  navigator.sendBeacon(configuration.rootApiUrl + 'jobevents', blob);
});

我的信标包含自定义标头,这就是我创建 Blob 的原因。

但是,这个请求似乎没有发生。由于窗口关闭,这特别难以调试。所以问题是,为什么我的信标没有发送?

【问题讨论】:

  • 我假设您验证了请求是在浏览器关闭时完成时发生的?
  • @Jorg 是的,我有。好主意,感谢您的检查,但在这种情况下,这不是问题。
  • 卸载本身也会触发吗?您也许可以使用alert 对其进行测试,看看它是否会阻止窗口关闭
  • @Jorg 我无法使用alert 进行测试(可能不允许,因为它是not allowed in onbeforeunload(请参阅注释部分)),但我可以通过代码进行调试。跨度>

标签: javascript window onbeforeunload navigator onunload


【解决方案1】:

问题是您可以使用 navigator.sendBeacon 设置的唯一标头是 Content-Type,您可以通过在 Blob 选项中设置 type 来设置它。必须修改服务器路由以适应没有 Authorization 标头的请求(我将其作为 URL 参数传递——对于 POST 请求来说很奇怪,但似乎是使用信标做到这一点的唯一方法)。最后是这样的:

$(global).bind('unload', function () {
  if(appState.jobId == null) return;

  let headers = {
    type: 'application/json'
  };

  let jobEventLoggingBody = {
    UserEmail: appState.user.email,
    Job: {
      Id: appState.jobId
    },
    Timestamp: '/Date(' + new Date().getTime() + ')/',
    EventOrigin: 'PdfReviewClient',
    Event: 'JobClosed'
  };
  let jobEventLoggingUrl = `${configuration.rootApiUrl}jobevents?jwt=${authenticationState.token}`;
  let jobEventLoggingBlob = new Blob([JSON.stringify(jobEventLoggingBody)], headers);
  navigator.sendBeacon(jobEventLoggingUrl, jobEventLoggingBlob);
});

另请参阅this question,它专门解决了在信标中发送标头的问题。

【讨论】:

  • 我遇到了同样的问题 - 我只需要将数据作为查询字符串发送。感谢您的 q + a。任何人都知道这是为什么(因为通常查询字符串用于 GET,并且由于 sendBeacon 是 POST 请求,我希望我发送的值在正文中)。
【解决方案2】:

不知道能不能帮到你。你可以用它来调试。

function logData() {
  var newWindow = window.open();
  newWindow.document.write("ohai");
}

window.addEventListener("unload", logData, false); 

【讨论】:

    猜你喜欢
    • 2013-04-04
    • 2013-12-13
    • 1970-01-01
    • 2018-05-15
    • 2018-05-15
    • 1970-01-01
    • 2017-09-30
    • 2014-11-17
    • 1970-01-01
    相关资源
    最近更新 更多