首页 文章

navigator.geolocation.getCurrentPosition有时候工作有时不会

提问于
浏览
194

所以我使用navigator.geolocation.getCurrentPosition jammy有一个相当简单的JS .

$(document).ready(function(){
  $("#business-locate, #people-locate").click(function() {
    navigator.geolocation.getCurrentPosition(foundLocation, noLocation);
  });

  navigator.geolocation.getCurrentPosition(foundLocation, noLocation);

  function foundLocation(position) {
    var lat = position.coords.latitude;
    var lon = position.coords.longitude;
    var userLocation = lat + ', ' + lon;
    $("#business-current-location, #people-current-location").remove();
    $("#Near-Me")
      .watermark("Current Location")
      .after("<input type='hidden' name='business-current-location' id='business-current-location' value='"+userLocation+"' />");
    $("#people-Near-Me")
      .watermark("Current Location")
      .after("<input type='hidden' name='people-current-location' id='people-current-location' value='"+userLocation+"' />");
  }
  function noLocation() {
    $("#Near-Me").watermark("Could not find location");
    $("#people-Near-Me").watermark("Could not find location");
  }
})//end DocReady

基本上这里发生的是我们得到当前位置,如果得到的话,两个“水印”被放置在两个字段中,表示“当前位置”,两个隐藏字段用lat-long数据作为它们的值(它们被删除)在一开始所以他们不会每次都重复) . 还有两个按钮,它们具有与之相关的点击功能,可以执行相同的操作 . 不幸的是,每三次左右,它都有效 . 这有什么问题???

21 回答

  • 5

    This library为地理位置调用添加了desiredAccuracy和maxWait选项,这意味着它将继续尝试获取位置,直到精度在指定范围内 .

  • 1

    感谢大家的投入,这对我有所帮助 .

    除了必须使用watchPosition()而不是getCurrentPosition()之外,我还发现我需要将来自document.ready()内的调用移动到头部 .

  • 315

    getCurrentPosition 失败时,使用IP地址地理位置服务作为回退方法可能是个好主意 . 例如我们的api https://ip-api.io

    $.getJSON("http://ip-api.io/json/",
        function(result) {
            console.log(result);
        });
    
  • 12

    我发现,这种方式不起作用

    navigator.geolocation.getCurrentPosition(function() {...}, function(err) {...}, {});
    

    But

    这种方式很完美

    function storeCoordinates(position) {
        console.log(position.coords.latitude, position.coords.longitude);
    }    
    
    function errorHandler() {...}
    
    navigator.geolocation.getCurrentPosition(storeCoordinates, errorHandler, { enableHighAccuracy: true, timeout: 20000, maximumAge: 0 });
    
  • 4

    我会在这里发布,以防它对任何人都有用......

    在iOS Safari上,如果我有一个活动的 navigator.geolocation.watchPosition 函数运行,对 navigator.geolocation.getCurrentPosition 的调用将会超时 .

    按照此处所述使用 clearWatch() 正确启动和停止 watchPosition ,工作:https://developer.mozilla.org/en-US/docs/Web/API/Geolocation/watchPosition

  • 36

    我一直有 exactly 同样的问题,几乎没有在网上找到有关它的信息 . 书中没有任何东西 . 最后,我在stackoverflow上找到了这个清醒的查询,并且(哈!)这是我在这里设置帐户所需的最终动力 .

    我有一个部分答案,但唉不完整 .

    首先,要意识到getCurrentPosition的 default timeoutinfinite (!) . 这意味着如果getCurrentPosition挂在后端的某个地方,你的错误处理程序将 never be called .

    为确保您获得超时,请将可选的第三个参数添加到对getCurrentPosition的调用中,例如,如果您希望用户在给他们了解发生的情况之前等待不超过10秒,请使用:

    navigator.geolocation.getCurrentPosition(successCallback,errorCallback,{timeout:10000});
    

    其次,我在不同的环境中经历了完全不同的可靠性 . 在家里,我会在一两秒钟内收到回调,但准确性很差 .

    然而,在工作中,我经历了相当奇怪的行为变化:地理位置一直在某些计算机上运行(IE当然除外),其他只能用于chrome和safari而不是firefox(gecko问题?),其他工作一次,然后是失败 - 模式从一小时变为一小时,从一天到一天 . 有时候你有一台“幸运”的电脑,有时却没有 . 也许在满月时屠宰山羊会有帮助吗?

    我无法理解这一点,但我怀疑在推动这一功能的各种书籍和网站中都有 the back end infrastructure is more uneven than advertised . 我真的希望他们能够更直接地了解这个功能是多么的好,并且 how important that timeout setting is, if you want your error handler to work properly .

    我一直在努力向学生们传授这些东西,并且在我自己的计算机(在投影仪和几个大屏幕上)默默地失败的情况下,这种情况令人尴尬,而大约80%的学生几乎立即得到了结果(使用完全相同的无线网络) . 当我的学生也在制作拼写错误和其他失误时,以及当我自己的电脑也失败时,很难解决这些问题 .

    无论如何,我希望这有助于你们中的一些人 . 谢谢你的理智检查!

  • 63

    这是我解决这个问题的一种黑客方式,至少它适用于所有当前的浏览器(在Windows上,我没有Mac):

    if (navigator.geolocation) {
        var location_timeout = setTimeout("geolocFail()", 10000);
    
        navigator.geolocation.getCurrentPosition(function(position) {
            clearTimeout(location_timeout);
    
            var lat = position.coords.latitude;
            var lng = position.coords.longitude;
    
            geocodeLatLng(lat, lng);
        }, function(error) {
            clearTimeout(location_timeout);
            geolocFail();
        });
    } else {
        // Fallback for no geolocation
        geolocFail();
    }
    

    如果有人点击关闭或选择否或在Firefox上选择“永不共享”选项,这也会有效 .

    笨重,但它的确有效 .

  • 12

    这对我来说每次都适用:

    navigator.geolocation.getCurrentPosition(getCoor, errorCoor, {maximumAge:60000, timeout:5000, enableHighAccuracy:true});
    

    虽然不是很准确 . 有趣的是,如果我在同一台设备上运行,它会让我离开大约100米(每次),但如果我去google的 Map ,它会完全找到我的位置 . 因此,尽管我认为enableHighAccuracy:true有助于它始终如一地工作,但似乎并没有让它更准确......

  • 2

    同样在这里的人,这在Chrome(稳定版,开发版和金丝雀版)中运行完美,而不是FF和Safari . 它也适用于我的iPhone和iPad(Safari!) . 这可能是由于此功能的相对新颖性(即它是一个错误) . 我现在花了将近一个星期的时间,我无法让它在这些浏览器上工作

    这是我发现的:

    第一次调用getCurrentPosition时,它完美无缺 . 任何后续调用都不会返回,即它不会触发successCallback或errorCallback函数 . 我在电话中添加了一些位置选项以证明我的观点:

    navigator.geolocation.getCurrentPosition(successCallback, errorCallback,  {timeout: 10000});
    

    它每次都超时(第一次成功通话后) . 我以为我可以使用maximumAge修复它,但这似乎没有工作,因为它可能会工作:

    navigator.geolocation.getCurrentPosition(successCallback, errorCallback,  {maximumAge:60000, timeout: 2000});
    

    这可以防止实际调用getCurrentPosition函数,如果你在60秒内调用它,但它忽略了这一点(但是,这可能是因为我实际刷新我的页面以触发第二次调用,不确定这是否持续调用)

    顺便说一句,甚至google's examples在这些浏览器上都失败了这让我相信这确实是浏览器错误,尝试它,在Safari中加载它两次,它将无法第二次工作 .

    如果有人找到解决方案,请告诉我:-)

    干杯 .

  • 3

    这已经是一个老问题,但所有答案都没有解决我的问题,所以让我们添加我最终找到的那个 . 它闻起来像一个黑客(它是一个),但总是在我的情况下工作 . 希望在你的情况下 .

    //Dummy one, which will result in a working next statement.
    navigator.geolocation.getCurrentPosition(function () {}, function () {}, {});
    //The working next statement.
    navigator.geolocation.getCurrentPosition(function (position) {
        //Your code here
    }, function (e) {
        //Your error handling here
    }, {
        enableHighAccuracy: true
    });
    
  • 0

    您没有收到错误消息,因为它默认没有超时(至少我认为) . 我和firefox有同样的问题只有我firefox总是给出一个超时 . 您可以像这样自己设置超时 .

    我已将最大年龄设置为Infinity,以确保没有问题 . 我的功能在chrome中运行得很好,但我每次都在firefox中超时 .

    navigator.geolocation.getCurrentPosition(
            function(position) {
                //do succes handling
            },
            function errorCallback(error) {
                //do error handling
            },
            {
                maximumAge:Infinity,
                timeout:5000
            }
        );
    

    我建议您仔细观察您的错误 . 应有尽有 . 为所有事情制定备份计划 . 我自己使用了数据库中的一些默认值或值,以防谷歌地理位置和导航地理位置失败 .

  • 6

    我在Mozilla有这个问题 . 所有时间: Error: Unknown error acquiring position .

    现在我正在使用47 Mozilla . 我已经尝试了一切,但这一切都是这个问题 . BUT 然后我在我的地址栏中打开 about:config ,转到 geo.wifi.ui 并将其值更改为“https://location.services.mozilla.com/v1/geolocate?key=test” . 作品!

    如果您有 Position acquisition timed out 错误,请尝试增加超时值:

    var options = {
      enableHighAccuracy: true,
      timeout: 5000,
      maximumAge: 0       
    };
    navigator.geolocation.getCurrentPosition(success, error, options);
    
  • 2

    所以我遇到了同样的事情 . 我尝试了有效但不可靠的超时解决方案 . 我发现如果你只是叫它两次,那么这个位置会正确刷新

    function getLocation(callback)
    {   
        if(navigator.geolocation)
        {
            navigator.geolocation.getCurrentPosition(function(position)
            {
                navigator.geolocation.getCurrentPosition(callback, function(){},{maximumAge:0, timeout:10000});
            },function(){}, {maximumAge:0, timeout:10000});
        }
        return true;
    }
    

    这当然有点慢,但我没有让它一次给我错误的位置 . 我已经让它超时了几次并且没有返回任何东西,但其他它然后效果很好 . 我知道这仍然有点hacky,我期待有人找到真正的解决方案 .

    或者如果你想确保它会继续尝试,直到你想放弃,你可以尝试这样的事情 .

    //example
    $(document).ready(function(){
        getLocation(function(position){
            //do something cool with position
            console.log(position);
        });
    });
    
    
    var GPSTimeout = 10; //init global var NOTE: I noticed that 10 gives me the quickest result but play around with this number to your own liking
    
    
    //function to be called where you want the location with the callback(position)
    function getLocation(callback)
    {   
        if(navigator.geolocation)
        {
            var clickedTime = (new Date()).getTime(); //get the current time
            GPSTimeout = 10; //reset the timeout just in case you call it more then once
            ensurePosition(callback, clickedTime); //call recursive function to get position
        }
        return true;
    }
    
    //recursive position function
    function ensurePosition(callback, timestamp)
    {
        if(GPSTimeout < 6000)//set at what point you want to just give up
        {
            //call the geolocation function
            navigator.geolocation.getCurrentPosition(
                function(position) //on success
            {
                    //if the timestamp that is returned minus the time that was set when called is greater then 0 the position is up to date
                if(position.timestamp - timestamp >= 0)
                    {
                        GPSTimeout = 10; //reset timeout just in case
                        callback(position); //call the callback function you created
                    }
                    else //the gps that was returned is not current and needs to be refreshed
                    {
                        GPSTimeout += GPSTimeout; //increase the timeout by itself n*2
                        ensurePosition(callback, timestamp); //call itself to refresh
                    }
                },
                function() //error: gps failed so we will try again
                {
                    GPSTimeout += GPSTimeout; //increase the timeout by itself n*2
                    ensurePosition(callback, timestamp);//call itself to try again
                },
                {maximumAge:0, timeout:GPSTimeout}
            )
        }       
    }
    

    我可能在这里有一些类型和一些拼写错误,但我希望你能得到这个想法 . 如果有人有疑问或有人找到更好的东西,请告诉我 .

  • 5

    我在2017年仍然得到了不稳定的结果,我有一个理论:the API documentation说这个电话现在只有"in a secure context",即通过HTTPS . 我在开发环境中获得结果时遇到问题(本地主机上的http),我相信这就是原因 .

  • 0

    这是我的解决方案,感谢封闭:

    function geoloc(success, fail){
        var is_echo = false;
        if(navigator && navigator.geolocation) {
          navigator.geolocation.getCurrentPosition(
            function(pos) {
              if (is_echo){ return; }
              is_echo = true;
              success(pos.coords.latitude,pos.coords.longitude);
            }, 
            function() {
              if (is_echo){ return; }
              is_echo = true;
              fail();
            }
          );
        } else {
          fail();
        }
      }
    
      function success(lat, lng){
        alert(lat + " , " + lng);
      }
      function fail(){
        alert("failed");
      }
    
      geoloc(success, fail);
    
  • 0

    @brennanyoung 's answer is great, but if you'想知道在失败的情况下该怎么做才能使用IP地理定位API,例如https://ipinfo.io(这是我的服务) . 这是一个例子:

    function do_something(coords) {
        // Do something with the coords here
        // eg. show the user on a map, or customize
        // the site contents somehow
    }
    
    navigator.geolocation.getCurrentPosition(function(position) { 
        do_something(position.coords);
        },
        function(failure) {
            $.getJSON('https://ipinfo.io/geo', function(response) { 
            var loc = response.loc.split(',');
            var coords = {
                latitude: loc[0],
                longitude: loc[1]
            };
            do_something(coords);
            });  
        };
    });
    

    有关详细信息,请参见http://ipinfo.io/developers/replacing-navigator-geolocation-getcurrentposition .

  • 1

    对于任何在iPhone应用程序上工作的人......

    如果您的代码在iOS 9上的UIWebView中运行,那么您必须在应用程序的plist中设置 NSLocationWhenInUseUsageDescription .

    如果你没有设置它,那么 getCurrentPosition 永远不会回叫,永远不会提示用户 .

  • 2

    我一直有类似的问题,并一直在研究浏览器可以调用getCurrentPosition的频率限制的可能性 . 我似乎经常可以获得一个位置,但如果我立即刷新页面它会超时 . 如果我等一下,我通常可以再次获得一个位置 . 这通常发生在FF上 . 在Chrome和Safari中,我还没有注意到getCurrentPosition超时 . 只是一个想法...

    虽然我找不到任何支持这一点的文档,但经过多次测试后我才得出结论 . 也许其他人有关于此的一些信息?

  • 4

    我终于在android中找到了firefox,chrome和默认导航器的工作版本(仅限4.2测试):

    function getGeoLocation() {
            var options = null;
            if (navigator.geolocation) {
                if (browserChrome) //set this var looking for Chrome un user-agent header
                    options={enableHighAccuracy: false, maximumAge: 15000, timeout: 30000};
                else
                    options={maximumAge:Infinity, timeout:0};
                navigator.geolocation.getCurrentPosition(getGeoLocationCallback,
                        getGeoLocationErrorCallback,
                       options);
            }
        }
    
  • 2

    传递给Geolocation.getCurrentPosition()的第二个参数是您要处理任何地理位置错误的函数 . 错误处理程序函数本身会收到一个PositionError对象,其中包含有关地理位置尝试失败原因的详细信息 . 如果您有任何问题,我建议将错误输出到控制台:

    var positionOptions = { timeout: 10000 };
    navigator.geolocation.getCurrentPosition(updateLocation, errorHandler, positionOptions);
    function updateLocation(position) {
      // The geolocation succeeded, and the position is available
    }
    function errorHandler(positionError) {
      if (window.console) {
        console.log(positionError);
      }
    }
    

    在我的代码中执行此操作后,显示消息“网络位置提供商位于'https://www.googleapis.com/ ' : Returned error code 400". Turns out Google Chrome uses the Google APIs to get a location on devices that don'已内置GPS(例如,大多数台式计算机).Google会根据用户的IP地址返回大致的纬度/经度 . 但是,在开发人员的构建中Chrome(例如Ubuntu上的Chromium)浏览器版本中没有包含API访问密钥 . 这会导致API请求无提示失败 . 有关详细信息,请参阅Chromium Issue 179686: Geolocation giving 403 error .

  • 1

    我最近自己注意到了这个问题,我不确定它是怎么发生的,但有时会出现firefox卡在缓存中加载的东西上 . 清除缓存并重新启动Firefox后,它似乎再次运行 .

相关问题