webentwicklung-frage-antwort-db.com.de

funktion schlägt nie vor, wenn der Benutzer die Geolocation in Firefox nicht freigibt

Also ich habe diesen Javascript-Code. Wenn der Benutzer in Safari und Chrome die Standortfreigabe ablehnt, funktioniert die Funktion nicht ordnungsgemäß. In Firefox ist dies jedoch nicht der Fall. 

Jede Hilfe wird geschätzt. 

function initGeolocation()
{
    if( navigator.geolocation )
    {          
          // Call getCurrentPosition with success and failure callbacks
          navigator.geolocation.getCurrentPosition( success, fail );
    }
    else
    {
          alert("Sorry, your browser does not support geolocation services.");
    }
}

 var map;
 function success(position)
 {

     var longIDText = document.getElementById('longID');
     var latIDText = document.getElementById('latID');
     longIDText.value = position.coords.longitude;
     latIDText.value = position.coords.latitude;
     document.getElementById('coordSubmitID').click();
  }

  function fail(error)
  {
          alert("FAAAAAAAAAAIIIIIIIIIL")
          var Zip_code ;
          while (true){
              // Could not obtain location

              Zip_code = Prompt("Please enter your current address or Zip code","");


              if ( Zip_code == "" ) {
                  alert(Zip_code +" is not a valid address. Please try again.");
              } 
              else{
                break;
              }
          }
          var zipIDText = document.getElementById('zipID');
          zipIDText.value = Zip_code;
          document.getElementById('coordSubmitID').click();
  }
47
theRealWorld

Für Firefox ist es scheint, dassPERMISSION_DENIED angehoben wird only, wenn "Never share" ausgewählt ist; Wenn der Dialog verworfen oder "Nicht jetzt" ausgewählt wird, passiert praktisch nichts - selbst auf Mozillas Geolocation Demo Wenn Sie die Berechtigungs-Benutzeroberfläche verwerfen, geschieht nichts.

Dies bedeutet, dass getCurrentPosition entweder zurückkehren kann, weil der Benutzer die Bestätigungs-UI geschlossen hat oder weil er die asynchrone Anforderung erfolgreich gestartet hat.

https://bugzilla.mozilla.org/show_bug.cgi?id=675533

29
Alex K.

Dies ist ein echter Schmerz und definitiv keine wünschenswerte Funktionalität.

Als Workaround verwende ich zum Speichern des auf ewig wartenden Benutzers das Festlegen eines Timeouts, um zu überprüfen, ob der Wait-Spinner nach 3 Sekunden angezeigt wird. Wenn ja, blenden Sie ihn aus und zeigen Sie eine manuelle Postleitzahl an:

var latlng;

var waitTime = 3000;
try {
    if (navigator.geolocation) {
        navigator.geolocation.getCurrentPosition(function (position) {
            success(position);
        }, showError);
    } else {
        showError("NOT-SUPPORTED");
    }
    var t = setTimeout(function () {
        if ($("#getZip div.loading").css("display") != "none") {
            $("#getZip div.loading").hide();
            $("#errorZip").show();
        }
    }, waitTime);
} catch (evt) {
    alert(evt);
}
21
Jamie

Alexleonard hat darauf hingewiesen, dass die einzige verlässliche Cross-Browser-Lösung, die ich dafür gefunden habe, eine setTimeout() ist, mit der der Status Ihres latLng-Objekts/der Variablen überprüft werden kann, da die timeout-Option von getCurrentPosition() nicht zuverlässig zu funktionieren scheint. Das folgende Beispiel wurde in IE11, Chrome33 und Firefox28 getestet.

Eine vollständigere Lösung, die ein jQuery-Versprechen verwendet, finden Sie unter Gist hier: https://Gist.github.com/GFoley83/10092929

Example - Drücke F12, füge es in die Konsole ein und führe aus.

var latLng,
    geoOptions = {
        enableHighAccuracy: false,
        timeout: 5000, // Wait 5 seconds
        maximumAge: 300000 //  Valid for 5 minutes
    };

var userLocationFound = function(position){
    latLng = {
        lat: position.coords.latitude,
        lng: position.coords.longitude
    };
    window.console.log("User confirmed! Location found: " + latLng.lat + ", " + latLng .lng);
}

var userLocationNotFound = function(){
    latLng = {
        lat: -41.29247, // fallback lat 
        lng: 174.7732  // fallback lng
    };
    window.console.log("Fallback set: ", latLng);
}

window.navigator.geolocation.getCurrentPosition(userLocationFound, userLocationNotFound, geoOptions);

setTimeout(function () {
    if(!latLng){
        window.console.log("No confirmation from user, using fallback");
        userLocationNotFound();
    }else{
        window.console.log("Location was set");
    }
}, geoOptions.timeout + 1000); // Wait extra second
13
GFoley83

Beachten Sie, dass dies eigentlich auch ein Problem in Chrome ist.

In Chrome wird ein Hinweis angezeigt, dass die Site Ihren Standort kennen soll. Sie bietet dann die Optionen "Zulassen" und "Verweigern" an. Bei der Gestaltung der Benutzeroberfläche wählt der Benutzer mit größerer Wahrscheinlichkeit entweder "Zulassen" oder "Ablehnen", wodurch eine Antwort an die Funktion navigator.geolocation.getCurrentPosition zurückgegeben wird. Der Benutzer kann jedoch auch auf ein "X" ganz rechts in der Mitteilung klicken. Dies ist im Wesentlichen das Gleiche wie das Klicken auf "Nicht jetzt" in Firefox. 

Es wird kein Ergebnis an die Funktion zurückgegeben. 

Sieht aus, als müsste ein Timer implementiert werden, um dieses mögliche Ergebnis zu berücksichtigen.

4
alexleonard

Dies ist nach Entwurf und ist anscheinend kein Thema. Siehe https://bugzilla.mozilla.org/show_bug.cgi?id=675533

Den Entwicklern, die diese Funktion verwenden, ist es überlassen, eine browserspezifische Problemumgehung für Firefox zu entwickeln.

Auf der Grundlage des Kommentars des FF-Entwicklers zur tatsächlichen Geolocation-Nutzung durch Endbenutzer werden offenbar die Firefox-Entwickler detaillierte Daten darüber gesammelt, was Endbenutzer mit ihren Produkten tun.

4
Chris

Verwenden Sie ein Versprechen. Ich verwende anglejs, das seine eigene Version von $ q hat, um das gleiche Problem zu lösen, das wir alle haben.

            $scope.ByUserPosition = function () {
                //http://www.w3.org/TR/geolocation-API/
                var deferred = $q.defer();

                deferred.promise.then(findByPosition, function (data) {
                    console.log('error', data);
                });

                var resolveBy = 1000 * 30;
                navigator.geolocation.getCurrentPosition(function (position) {
                    deferred.resolve({ latitude: position.coords.latitude, longitude: position.coords.longitude });
                }, function (err) {
                    deferred.reject(err);
                }, {
                    enableHighAccuracy: true,
                    timeout: resolveBy,
                    maximumAge: 0
                });

                $timeout(function() {
                    deferred.reject('timed out');
                }, resolveBy)
            };
3
Leblanc Meneses

Die einzige Lösung für dieses Problem ist wie folgt:

  1. Wenn der Benutzer auf die Schaltfläche klickt, um seinen Standort automatisch abzurufen, zeigen Sie den Spinner und einen Link daneben "ex: Cancel".
  2. Wenn er den Standort freigibt, dann kein Problem. Wenn er sich entschließt, das Firefox-Popup zu schließen, wird der Spinner zwar angezeigt, er kann jedoch auf "Abbrechen" klicken, um den Spinner zu stoppen. Dies ist ein Indikator für das Schließen des Popups

Ich hoffe das hilft :)

1
AMustafa

Bearbeiten (nach einem Downvote) 6-11-2013

Wie unter dieser Antwort erwähnt, löst dies das Problem nicht, wenn ein Benutzer den Zugriff auf den Standort verweigert. Zum Downvote gehört das. Ich halte die Antwort hier, weil das Timeout so ist, was man sowieso verwenden sollte, und ich sehe es in keiner Antwort.

Die Funktion navigator.geolocation.getCurrentPosition () hat die Option, das Timeout mit zu senden:

navigator.geolocation.getCurrentPosition(
     function (position){
        //do someting with position
     },
     function (error){
        // do something with the error (like the code)
     }, 
     {timeout:10000}
);

und einige andere Optionen, wie das Alter der zwischengespeicherten Position (maximumAge) . das Zeitlimit und der Maximalwert werden in Millisekunden angegeben, also 10000 = 10 Sekunden.

Das Standard-Timeout ist übrigens unendlich ... Wenn Sie also kein Timeout festlegen, ruft es den Rückruf niemals für Fehler auf.

so in der Option wie Jamie antwortete, würde ich sagen:

if (navigator.geolocation) {
        navigator.geolocation.getCurrentPosition(function (position) {
            success(position);
        }, showError, {timeout:3000});
    }
1
michel.iamit

Hier ist eine Lösung für mein Problem mit Vanilla es6 Promises. Inspiriert durch die Antwort von @LeblancMeneses.

if(navigator.geolocation) {
  let promise = new Promise((resolve, reject) => {
    navigator.geolocation.getCurrentPosition(
      (position) => {
        resolve(position)
      },
      (error) => {
        resolve(error)
      }
    )
    window.setTimeout(() => {
      resolve({})
    }, 8000)
  })
  promise.then((result) => {
      // do something with result
  })
} else {
  console.log('no geolocation available')
}
0
Harry Moreno