该脚本在 Mozilla Firefox 中不起作用

The script is not working in Mozilla Firefox

我需要在页面关闭或刷新时向服务器发送一些数据。因此,我创建了一个简单的脚本来满足我的需求。问题是这个脚本 在 Mozilla firefox.

中不工作

该脚本可在许多其他浏览器中运行,例如 chrome、chromium、brave、opera、falkon、epiphany、qutebroser、Midori、safari、edge。 只有 firefox 有问题

var timeLog = {
    start: null,
    end: null,

    init: function () {
        this.start = new Date().getTime();
    },

    sendResults: function () {
        this.end = new Date().getTime();
        var url = "tracker";
        url += "?" + "start=" + this.start;
        url += "&" + "end=" + this.end;
        url += "&" + "User-Agent-JS=" + navigator.userAgent;
        url += "&" + "url=" + window.location.toString();

        fetch(url, {
            method: 'POST',
            headers: {'Content-Type': 'application/json'},
            keepalive: true
        });
    }
};

window.onbeforeunload = function () {
    timeLog.sendResults();
};

timeLog.init();

错误信息为: 未捕获(承诺)类型错误:尝试获取资源时出现网络错误。

编辑: 如果 onbeforeunload 的事件在这里注册:

window.onbeforeunload = async function(event){
    event.preventDefault();
    timeLog.sendResults();
};

它正在运行,但我需要确认我要离开该页面。

正如我在互联网上发现的那样,问题的出现是因为 firefox 使用其自己的 fetch.

实现

--------------------解决方案 [仍然无法在 Firefox 中正常工作]------------ ------------

window.onbeforeunload = function (event) {
    event.preventDefault();
    timeLog.sendResults();
    delete event['returnValue'];
};

------------------------解决方案-------------------- ----

我使用了 sendBeacon 而不是 fetch

所以最终代码如下:

/*      ----REPLACED----
        fetch(url, {
            method: 'POST',
            headers: {'Content-Type': 'application/json'},
            keepalive: true
        });
*/        
        navigator.sendBeacon(url);

让我们添加更多代码以查看发生了什么,允许 fetch 完成然后处理任何错误(暂停以查看它)然后如果没有发生错误则继续卸载 - 我们期望的情况.

var timeLog = {
  start: null,
  end: null,

  init: function() {
    this.start = new Date().getTime();
  },

  sendResults: function() {
    this.end = new Date().getTime();
    var url = "tracker";
    url += "?" + "start=" + this.start;
    url += "&" + "end=" + this.end;
    url += "&" + "User-Agent-JS=" + navigator.userAgent;
    url += "&" + "url=" + window.location.toString();

    return fetch(url, {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json'
      },
      keepalive: true
    });
  }
};

window.addEventListener('beforeunload', function(e) {
  // Cancel the event
  // e.preventDefault(); // If you prevent default behavior in Mozilla Firefox prompt will always be shown
  // Chrome requires returnValue to be set
  // e.returnValue = '';

  let myfetch = timeLog.sendResults();
  myfetch
    // borrowed code https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch
    .then(response => {
      //do something with response
      const contentType = response.headers.get('content-type');
      if (!contentType || !contentType.includes('application/json')) {
        throw new TypeError("Oops, we haven't got JSON!");
      }
      return response.json();
    })
    .then(data => {
      /* process your data further */
    })
    .catch(error => {
      console.error(error);
      e.preventDefault(); // pause to see the error in console
    });
  // the absence of a returnValue property on the event will guarantee the browser unload happens
  delete e['returnValue'];
});

timeLog.init();