Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Beacon API Cannot load <url> due to access control checks when navigating to new page

I have a navigation.sendBeacon request being sent during a pagehide event on Safari with some analytics data to an endpoint on the same domain as the current page. This works fine when the tab is being closed, but when navigating to a new url, Safari throws Beacon API Cannot load <url> due to access control checks while trying to make the request.

This issue does not occur on Chrome, and there are no other logs shown. I don't think this is a CORS request, all domains and subdomains are the same.

Has anyone else seen this or know how to fix?

like image 836
RyanCheu Avatar asked Apr 26 '18 22:04

RyanCheu


1 Answers

Using any sort of Asynchronous HTTP request, whether it is sendBeacon, fetch, or XMLHttpRequest seems to have problems in both desktop and iOS Safari at the moment when inside a pagehide event. I have received versions of the same error such as Fetch API cannot load ... due to access control checks when I use different types of HTTP requesters within the pagehide event. I am sure that it is not a CORS error, since the exact same request does not have a problem outside of a pagehide event.

While not recommended due the its blocking of the main thread, I am using synchronous requests until the bug is patched in Safari. For my use case, it is more critical that the analytics data from pagehide is successfully sent even even though it causes a small delay to the end user. Synchronous HTTP requests are a meh workaround until the bug is remediated, which hopefully is soon since the link from @Phillip Walton suggests that a patch has been accepted but obviously has not been released yet.

if (isSafari && pageHideBroken) {
    $.ajax({
        type: "POST",
        async: false, //The most important line
        url: `https://`,
        data: 'Goodbye',
        timeout: 5000
                });
}
else {
    navigator.sendBeacon(`https://`, 'Goodbye');
}

I have confirmed that on both Desktop Safari and iOS Safari that my backend successfully receives the data using this approach. JQuery is not required to make a sync HTTP request, but I just used $.ajax as the example due to its conciseness compared to XMLHttpRequest. If you make this workaround conditional like I have, then it is easy to swap back to navigator.sendBeacon once the bug is fixed! This type of browser-dependent behavior is never fun to code around.

like image 118
Henry Agnew Avatar answered Oct 24 '22 05:10

Henry Agnew