web-dev-qa-db-fra.com

API Beacon Impossible de charger <url> en raison de contrôles de contrôle d'accès lors de la navigation vers une nouvelle page

Une demande navigation.sendBeacon est envoyée pendant un événement pagehide sur Safari avec des données d'analyse sur un noeud final du même domaine que la page actuelle. Cela fonctionne bien lorsque l'onglet est en cours de fermeture, mais lorsque vous naviguez vers une nouvelle URL, Safari lance Beacon API Cannot load <url> due to access control checks lors de la tentative de création de la demande.

Ce problème ne se produit pas sur Chrome et aucun autre journal n'est affiché. Je ne pense pas qu'il s'agisse d'une demande CORS, tous les domaines et sous-domaines sont identiques.

Est-ce que quelqu'un d'autre a vu cela ou sait comment y remédier?

6
RyanCheu

L'utilisation de toute sorte de requête HTTP asynchrone, que ce soit sendBeacon, fetch ou XMLHttpRequest, semble rencontrer des problèmes à la fois sur le bureau et sur iOS Safari au moment où ils se trouvent dans un événement pagehide. J'ai reçu des versions de la même erreur, telles que Fetch API cannot load ... due to access control checks, lorsque j'utilise différents types de demandeurs HTTP dans l'événement pagehide. Je suis sûr que ce n'est pas une erreur CORS, car la même demande n'a pas de problème en dehors d'un événement pagehide.

Bien que cela ne soit pas recommandé en raison du blocage du thread principal, j'utilise des requêtes synchrones jusqu'à ce que le bogue soit corrigé dans Safari. Pour mon cas d'utilisation, il est plus important que les données d'analyse de pagehide soient envoyées avec succès même si cela cause un léger retard à l'utilisateur final. Les requêtes HTTP synchrones constituent une solution de rechange jusqu'à la résolution du bogue, ce qui, espérons-le, le sera bientôt puisque le lien de @Phillip Walton suggère qu'un correctif a été accepté mais qu'il n'a évidemment pas encore été publié.

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

J'ai confirmé que, sur Desktop Safari et iOS Safari, mon backend reçoit correctement les données à l'aide de cette approche. JQuery n'est pas obligé de faire une requête HTTP de synchronisation, mais je viens d'utiliser l'exemple $.ajax en raison de sa concision par rapport à XMLHttpRequest. Si vous effectuez cette solution de contournement comme je l’ai fait, il est facile de revenir à navigator.sendBeacon une fois le bogue corrigé! Ce type de comportement dépendant du navigateur n’est jamais amusant à coder. 

1
Henry Agnew