Почему мой вызов проверки активности при выгрузке страницы не работает в Safari?

Мне нужно отправить немного данных для отчета, когда пользователь закрывает или покидает определенную страницу. Поэтому я настроил конечную точку API и использую window.fetch с установленным флагом keepalive, чтобы убедиться, что вызов завершается, даже если страница полностью выгружается.

Рассматриваемый вызов Javascript выглядит следующим образом:

async onLeavingPage() {
    (preparing data for call)
    const response = await fetch(
        (url),
        {
            keepalive: true,
            method: "POST",
            mode: "cors",
            headers: {
                "Content-Type": "application/json",
                Authorization: axios.defaults.headers.common["Authorization"]
            },
            body: JSON.stringify({})
        }
    );
    console.log(response);
}

Я вызываю его, наблюдая за событием pagevisibility и вызывая его, когда страница скрыта или закрыта, используя библиотеку жизненного цикла страницы.

lifecycle.addEventListener("statechange", (e) => {
            if (e.newState === "hidden" || e.newState === "terminated") {
                this.onLeavingPage();
            }
        });

Предпочтительным поведением является завершение вызова, даже если страница перезагружается или нажимается другая ссылка. Но из-за этой ошибки CORS этого не происходит. Он отлично работает в Chrome и Firefox, но в Safari происходит сбой с этим сообщением об ошибке в консоли:

Fetch API не может загрузиться (конечная точка API) из-за проверок управления доступом.

Тот же самый вызов fetch работает в Safari, если он вызывается в любых других обстоятельствах (например, при нажатии на ссылку или сворачивании, а затем развертывании страницы), так что это что-то особенное для вызова его при выгрузке страницы.


person Dark Phoenix    schedule 13.01.2021    source источник
comment
Возможно, вы сталкиваетесь с известной ошибкой в ​​Safari, связанной с изменением видимости, которое не срабатывает, как ожидалось, во время навигации по страницам; см. bugs.webkit.org/show_bug.cgi?id=151234. Возможно, попробуйте протестировать в Safari Technology Preview и посмотрите, работает ли он там, как ожидалось.   -  person sideshowbarker    schedule 14.01.2021
comment
stackoverflow.com/q/57393717/441757 и stackoverflow.com/q/48101355/441757 может быть вызвано той же основной проблемой.   -  person sideshowbarker    schedule 14.01.2021
comment
Я думаю, что обходной путь, который вы, возможно, захотите попробовать, — это прослушивать событие pagehide, которое надежно срабатывает в Safari, даже если visibilitychange нет.   -  person sideshowbarker    schedule 14.01.2021
comment
У меня было console.log при изменении видимости. Насколько я вижу, он работает, как и ожидалось, даже в Safari. Я использую npmjs.com/package/page-lifecycle для обнаружения событий жизненного цикла, и у него есть код для обработки Safari, который не запускает постоянное изменение видимости. Хотя мне интересно, может ли иметь какое-то отношение к этому тот факт, что Safari использует beforeunload в качестве замены.   -  person Dark Phoenix    schedule 14.01.2021
comment
Хорошо, да, я догадался, что библиотека должна быть достаточно умной, чтобы абстрагироваться от проблемы Safari. Но в любом случае мне все еще интересно, является ли ошибка CORS побочным эффектом какой-то другой проблемы, а не наоборот. Я предполагаю, что один из способов изолировать это — повторить все это в тестовой среде, где код внешнего интерфейса и конечная точка API имеют одно и то же происхождение, а не перекрестное происхождение. Если бы это не сработало, даже когда запрос имеет тот же источник, то вы бы знали, что основная причина не была проблемой CORS — и, конечно, с другой стороны, если бы это сработало, вы бы знали, что причина действительно должна быть проблема CORS.   -  person sideshowbarker    schedule 14.01.2021
comment
Возможно, вы захотите обновить вопрос, чтобы вставить точные сообщения об ошибках, которые браузер регистрирует в консоли Safari Web Inspector, а также вставить все заголовки запросов для всех запросов (включая предварительный запрос OPTIONS) и заголовки ответов. . И вы должны проверить код состояния HTTP как для ответов OPTIONS, так и для ответов POST. Вы можете получить доступ ко всему этому на вкладке «Сеть» в Safari Web Inspector.   -  person sideshowbarker    schedule 14.01.2021