如果用户拒绝在Firefox中共享地理位置,则不会调用该函数

所以我有这个JavaScript代码。 在safari和chrome中,如果用户拒绝共享位置,它应该会失败。 但是,在Firefox中,它不。

任何帮助赞赏。

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(); } 

对于Firefox来说, PERMISSION_DENIED 似乎 在select“Never share” 如果对话被解散或select“不是现在”,实际上什么都不会发生 – 即使在Mozilla地理位置演示中,如果您解除权限,UI也不会发生任何事情。

这意味着getCurrentPosition可以返回,因为用户closures了确认UI,或者因为它成功地启动了asynchronous请求 – 似乎没有办法区分这两者。

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

这是一个真正的痛苦,肯定不是所希望的function。

我用来保存用户等待的解决方法是设置超时,以检查等待微调器是否显示3秒后,如果是,隐藏它,并显示手动邮政编码input:

 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); } 

正如alexleonard所指出的那样,我发现的唯一可靠的,跨浏览器的解决scheme是使用setTimeout()来检查latLng对象/variables的状态,因为getCurrentPosition()timeout选项似乎没有可靠地工作。 下面的例子在IE11,Chrome33和Firefox28中进行了testing。

对于使用jQuery承诺的更完整的解决scheme,请查看我的Gist: https : //gist.github.com/GFoley83/10092929

例子 – 点击F12,粘贴到控制台并运行

 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 

这是按devise,显然是一个没有问题。 见https://bugzilla.mozilla.org/show_bug.cgi?id=675533

这是由使用该function的开发人员为Firefox提供一个特定于浏览器的工作。

值得注意的是,根据FF开发者对最终用户的实际地理位置使用情况的评论,显然Firefox开发者正在收集关于最终用户对他们的产品做什么的详细数据。

请注意,这实际上也是Chrome中的一个问题。

在Chrome浏览器中会出现一个build议通知,“网站想知道您的位置” – 然后提供“允许”和“拒绝”作为选项。 通过UIdevise,用户更可能selectAllow或Deny,然后返回navigator.geolocation.getCurrentPosition函数的答案。 但是,用户也可以点击咨询通知最右侧的“X”。 这与在Firefox中单击“不是现在”基本相同。

没有结果返回给函数。

看起来像一个计时器必须执行,以允许这种可能的结果。

使用承诺。 我使用的是具有它自己版本的$ q的angularjs来解决我们都有的同样的问题。

  $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) }; 

编辑(在downvote后)6-11-2013

正如下面这个答案所指出的,当用户拒绝访问位置时,这并不能解决问题。 对downvote是正确的。 我在这里保留了答案,因为超时是一个应该使用的东西,我不会在任何答案中看到它。

函数navigator.geolocation.getCurrentPosition()可以select发送超时值:

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

和其他一些选项,如caching位置(maximumAge)的年龄。 超时和最大图像以毫秒为单位,所以10000 = 10秒。

顺便说一下,默认超时是无限的…所以如果你不设置超时,它将永远不会调用callback的错误….

所以在像杰米这样的select中,我会说:

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

解决这个问题的唯一办法如下:

  1. 当用户点击button自动获取他的位置时,显示微调框和旁边的链接“ex:取消”。
  2. 如果他启用共享位置,那么没有问题。 如果他决定解散Firefox的popup窗口,微调框仍然会显示,但他可以点击“取消”链接,以停止微调的指示器解散popup

我希望这有帮助 :)

这是使用vanilla es6 Promises解决我的问题。 受@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') } 
 var latlng; if (navigator.geolocation) { navigator.geolocation.getCurrentPosition(function (position) { latlng = new google.maps.LatLng(position.coords.latitude, position.coords.longitude); }); } if(!latlng) { latlng = new google.maps.LatLng(57.718, 11.974); } 

Handeld所有我的错误:)

watchPosition和getCurrentPosition都接受第二个callback,当有错误时调用它。 错误callback为错误对象提供了一个参数。 对于被拒绝的权限,error.code将是error.PERMISSION_DENIED(数值1)。

在这里阅读更多信息: https : //developer.mozilla.org/en/Using_geolocation

例:

 navigator.geolocation.watchPosition(function(position) { console.log("i'm tracking you!"); }, function (error) { if (error.code == error.PERMISSION_DENIED) console.log("you denied me :-("); 

});