navigator.geolocation.getCurrentPosition有时候有时不起作用
所以我有一个非常简单的JS使用navigator.geolocation.getCurrentPosition jammy。
$(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
基本上这里发生了什么是我们得到当前位置,如果获得,两个“水印”被放置在两个领域,说“当前位置”和两个隐藏的领域创build与拉长的数据作为他们的价值(他们被删除在一开始,所以他们不会得到每一次重复)。 还有两个button有一个点击function绑定到他们做同样的事情。 不幸的是,每隔三次左右,它就会起作用。 这里有什么问题?
我一直有完全相同的问题,几乎没有在网上find关于它的信息。 书中没有任何东西。 最后,我在stackoverflow上发现了这个清醒的查询,并且(ha!)这是我在这里build立一个帐户所需要的最后的动力。
我有一个部分的答案,但不是一个完整的。
首先,要明白getCurrentPosition的默认超时是无限的 (!)。 这意味着如果getCurrentPosition挂在后端的某个地方,你的error handling程序将永远不会被调用 。
为了确保获得超时,请将可选的第三个参数添加到getCurrentPosition的调用中,例如,如果您希望用户等待不超过10秒钟,然后给他们一些线索,请使用:
navigator.geolocation.getCurrentPosition(successCallback,errorCallback,{timeout:10000});
其次,在不同的情况下,我经历了不同的可靠性。 在家里,我可以在一两秒钟内回复,虽然准确性很差。
然而,在工作中,我经历了很奇怪的行为变化:地理位置一直在一些计算机上工作(当然,IE除外),其他人只在铬和Safari浏览器中工作,而不是Firefox(壁虎问题),其他工作一次,然后失败 – 并且模式每小时都在变化,每天都在变化。 有时你有一台“幸运”的电脑,有时候不是。 也许在满月时宰杀山羊会有帮助吗?
我一直无法理解这一点,但我怀疑后端基础设施比在各种推动这一function的gung-ho书籍和网站上宣传的更加不均衡 。 我真的希望,如果你希望你的error handling程序能够正常工作,那么他们会更直截了当地说明这个function是多么的重要 ,以及这个超时设置有多重要 。
我一直在试图把这些东西传授给学生们,而且我的电脑(在投影机和几个大屏幕上)静静地失败了,而大约80%的学生几乎立即得到了结果(使用完全相同的无线networking)。 当我的学生也犯了错别字和其他错误,以及当我自己的电脑也失败时,解决这些问题是非常困难的。
无论如何,我希望这可以帮助你们中的一些人。 感谢您的理智检查!
这是我解决这个问题的方法,至less它可以在所有当前的浏览器(在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(); }
如果有人点击closures或者select否,或者在Firefox上select从不共享选项,这也将起作用。
笨重,但它的作品。
这每次都适用于我:
navigator.geolocation.getCurrentPosition(getCoor, errorCoor, {maximumAge:60000, timeout:5000, enableHighAccuracy:true});
虽然不是很准确。 有趣的是,如果我在同一台设备上运行它,它会使我离开大约100米(每次),但是如果我去Google的地图,它会发现我的位置。 所以,虽然我认为enableHighAccuracy:true可以帮助它始终如一地工作,但似乎并没有使它更准确。
同样在这里的人,这在Chrome(稳定,开发和金丝雀),而不是在FF和Safari中工作完美顺便。 它也适用于我的iPhone和iPad(Safari!)。 这可能是由于这个function的相对新颖性(即它是一个错误)。 我现在花了差不多一个星期的时间,而我却无法在这些浏览器上工作
这是我发现的:
你第一次调用getCurrentPosition它是完美的。 任何后续调用永远不会返回,即它不会触发successCallback或errorCallback函数。 我在电话中添加了几个位置选项来certificate我的观点:
navigator.geolocation.getCurrentPosition(successCallback, errorCallback, {timeout: 10000});
并且每次(第一次成功通话后)超时。 我以为我可以用maximumAge修复它,但是这似乎并没有工作,因为它可以工作:
navigator.geolocation.getCurrentPosition(successCallback, errorCallback, {maximumAge:60000, timeout: 2000});
如果你在60秒内调用getCurrentPosition函数,它会阻止实际调用getCurrentPosition函数,但是它会忽略这个(但是,这可能是因为我实际上刷新了我的页面来触发第二个调用,不知道这是否是持续的通过调用)
顺便说一句,即使谷歌的例子在这些浏览器上失败,这导致我相信,这确实是浏览器的错误,尝试它,在Safari中加载两次,它不会工作的第二次。
如果有人find这个解决scheme,请让我知道:-)
干杯。
你不会得到一个错误消息,因为它默认没有超时(至less我认为)。 我曾经遇到同样的问题,只为我的Firefox的Firefox总是给一个超时。 你可以像这样设置超时时间。
我已经将最大年龄设置为无穷大,以确保没有问题。 我的function在chrome中效果很好,但是我每次都在firefox中得到超时。
navigator.geolocation.getCurrentPosition( function(position) { //do succes handling }, function errorCallback(error) { //do error handling }, { maximumAge:Infinity, timeout:5000 } );
我build议仔细观察你的错误。 预计一切。 有一个备份计划的一切。 我自己的数据库中使用了一些默认值或值,以防Google地理位置和导航地理位置都失败。
所以我遇到了同样的事情 我试过超时解决scheme,但工作但不可靠。 我发现,如果你只是调用两次,位置刷新正确
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; }
这当然是有点慢,但我没有给它一次错误的位置。 我已经有几次达到暂停,并没有返回任何东西,但除此之外,它的效果很好。 我知道这还是有点黑客,我期待有人find真正的解决scheme。
或者如果你想确定它会继续尝试,直到你想放弃,你可以尝试这样的事情。
//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} ) } }
我可能在这里有一些typeos和一些拼写错误,但我希望你明白了。 让我知道如果有人有问题,或者如果有人发现更好的东西。
这是我的解决scheme,谢谢closures:
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);
这已经是一个老问题了,但是所有的答案都没有解决我的问题,所以让我们添加一个我终于find的问题。 它闻起来像一个黑客(这是一个),但总是在我的情况下工作。 希望你的情况也是如此。
//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 });
@ brennanyoung的答案是好的,但是如果你想知道在失败的情况下怎么做,你可以使用一个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 。
我一直有类似的问题,并一直在研究浏览器可以调用getCurrentPosition的频率的限制的可能性。 似乎我经常可以得到一个位置,但是如果我立即刷新页面,它会超时。 如果我等一下,我通常可以再次获得一个位置。 这通常发生在FF。 在Chrome和Safari中,我还没有注意到getCurrentPosition超时。 只是一个想法…
虽然我找不到任何文件来支持这个,但这是我经过多次testing才得出的结论。 也许别人有这方面的一些信息?
传递给Geolocation.getCurrentPosition()
的第二个参数是要处理任何地理位置错误的函数。 error handling函数本身会接收一个PositionError
对象,其中包含有关为什么地理位置尝试失败的详细信息。 如果您有任何问题,我build议将错误输出到控制台:
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/ ”networking位置提供程序的消息:“返回的错误代码400”。 谷歌浏览器使用Google API在没有内置GPS的设备上获取位置(例如,大多数台式计算机)。 Google根据用户的IP地址返回近似的纬度/经度。 但是 ,在Chrome的开发人员版本(如Ubuntu上的Chromium)中,浏览器版本中不包含API访问密钥。 这会导致API请求无提示失败。 请参阅Chromium问题179686:地理位置给出403错误的细节。
我终于find了一个工作版本的Firefox,铬&默认导航在Android(4.2只testing):
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); } }
对于任何人在iPhone应用程序工作…
如果你的代码运行在iOS 9+的UIWebView上,那么你必须在应用程序的plist中设置NSLocationWhenInUseUsageDescription
。
如果你没有设置它,那么getCurrentPosition
将永远不会callback,用户永远不会被提示。
我在Mozilla中遇到了这个问题。 所有时间: 错误:未知错误获取位置 。
现在我正在使用47个Mozilla。 我已经尝试了一切,但所有的时间都是这个问题。 但是,然后我打开about:configuration在我的addsress栏,去geo.wifi.ui并将其值更改为“ https://location.services.mozilla.com/v1/geolocate?key=test ”。 作品!
如果您有位置获取超时错误,请尝试增加超时值:
var options = { enableHighAccuracy: true, timeout: 5000, maximumAge: 0 }; navigator.geolocation.getCurrentPosition(success, error, options);
我仍然在2017年得到零星的结果,我有一个理论: API文档说,现在只有“安全的上下文”,即通过HTTPS的调用。 我无法在我的开发环境(http on localhost)中获得结果,我相信这是为什么。
我最近自己注意到了这个问题,我不确定它是如何发生的,但是有时候Firefox会被加载到caching中。 清除caching并重新启动Firefox后,它似乎再次运行。
这个库为地理定位调用添加了desiredAccuracy和maxWait选项,这意味着它将继续尝试获取位置,直到精度在指定的范围内。
感谢大家的意见,这对我有帮助。
除了必须使用watchPosition()而不是getCurrentPosition()之外,我还发现我需要将document.ready()中的调用移动到头部。
当getCurrentPosition
失败时,使用IP地址地理位置服务作为回退方法可能是一个好主意。 例如与我们的API https://ip-api.io
$.getJSON("http://ip-api.io/json/", function(result) { console.log(result); });
我会在这里发布,以防万一它对任何人有用…
在iOS Safari上,如果我有一个活动的navigator.geolocation.watchPosition
函数正在运行,则对navigator.geolocation.getCurrentPosition
调用会超时。
使用clearWatch()
正确启动和停止watchPosition
如下所述: https : //developer.mozilla.org/en-US/docs/Web/API/Geolocation/watchPosition
如果在Google Chrome浏览器上无效,则需要使用HTTPS网域网页
请观看以下链接: https : //developers.google.com/web/updates/2016/04/geolocation-on-secure-contexts-only