navigator. gelocation . 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
基本上,这里发生的事情是我们得到当前位置,如果它得到了,两个“水印”被放置在两个字段中,表示“当前位置”,两个隐藏字段被创建,并使用latong数据作为它们的值(它们在开始时被删除,这样它们就不会每次都被重复)。还有两个按钮,它们有一个点击功能,做同样的事情。 不幸的是,每隔三次左右,它就会奏效。 这里有什么问题?< / p >
327965 次浏览

大家也一样,顺便说一句,这在Chrome(稳定,开发和金丝雀)中工作完美,只是在FF和Safari中不合适。它在我的iPhone和iPad上也很好用(Safari!)这可能是由于这个功能相对较新(即它是一个bug)。我现在花了差不多一个星期的时间在这个上面,我就是不能让它在那些浏览器上工作

以下是我的发现:

第一次调用getCurrentPosition时,它工作得很完美。任何后续调用都不会返回,也就是说,它不会触发successCallback或errorCallback函数。为了证明我的观点,我在看涨期权中添加了几个仓位选项:

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

并且每次都超时(在第一次成功调用之后)。我认为我可以用maximumAge来修复它,但这似乎并不像它应该工作的那样工作:

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

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

顺便说一句,即使谷歌的例子失败在这些浏览器上,这让我相信这确实是浏览器的bug,尝试一下,在Safari中加载两次,第二次就不会工作了。

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

欢呼。

我一直有完全同样的问题,在网上几乎找不到关于它的信息。书里什么都没有。最后,我在stackoverflow上找到了这个清醒的查询(哈!),这是我需要在这里建立一个帐户的最后动力。

我有一个部分的答案,但可惜不是一个完整的答案。

首先,要意识到getCurrentPosition的默认超时无限(!)。这意味着如果getCurrentPosition挂在后端某个地方,你的错误处理程序将永远不要被呼叫

为了确保你得到一个超时,添加可选的第三个参数到你对getCurrentPosition的调用,例如,如果你想让用户等待不超过10秒,然后给他们一个线索发生了什么,使用:

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

其次,我在不同的环境中经历了非常不同的可靠性。在家里,我在一两秒钟内就会收到回复,尽管准确率很低。

然而,在工作中,我经历了相当奇怪的行为变化:地理定位在一些电脑上一直有效(当然IE除外),另一些只能在chrome和safari上工作,但不能在firefox上工作(壁虎问题?),另一些只工作了一次,然后就失败了——这种模式每小时都在变化,每天都在变化。有时你有一台“幸运”的电脑,有时没有。也许满月时宰山羊会有帮助?

我还不能理解这一点,但我怀疑后端基础设施比宣传的更加不平衡在各种热心的书籍和网站上都在推动这个功能。我真的希望他们能更直接地说明这个功能是多么古怪,并且如果您希望错误处理程序正常工作,那么超时设置有多重要

今天我一直在试着教学生这些东西,遇到了一个尴尬的情况,我自己的电脑(在投影仪和几个大屏幕上)无声地失败了,而大约80%的学生几乎立即得到了结果(使用完全相同的无线网络)。当我的学生也犯拼写错误和其他错误时,当我自己的电脑也出现故障时,解决这些问题是非常困难的。

不管怎样,我希望这对你们中的一些人有所帮助。谢谢你的健康检查!

你不会得到一个错误消息,因为默认情况下它没有超时(至少我认为)。我用firefox也遇到过同样的问题,只是对我来说,firefox总是超时。您可以像这样自己设置一个超时。

我的功能在chrome中工作得很好,但我每次在firefox中都会超时。

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

我建议你仔细观察你的错误。一切都被期待。为每件事都准备一个备份计划。我使用一些默认值或值从我的数据库自己的情况下谷歌地理位置和导航地理位置失败。

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

虽然我找不到任何文档来支持这一点,但这是我经过多次测试后得出的结论。也许其他人有这方面的信息?

这是我解决这个问题的hack方法,至少它在所有当前的浏览器中都有效(在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上选择“永不共享”选项,这也会起作用。

很笨拙,但很有效。

以下是我的解决方案,感谢一个闭包:

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

这对我来说每次都管用:

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

虽然它不是很准确。有趣的是,在同一台设备上,如果我运行这个程序,它会把我拖走大约100米(每次),但如果我去谷歌的地图,它会准确地找到我的位置。因此,尽管我认为enableHighAccuracy: true有助于它始终如一地工作,但它似乎并没有使它更准确……

我也遇到了同样的情况。我尝试了超时解决方案,但不可靠。我发现如果你只调用它两次,位置就会正确刷新

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

这当然是有点慢,但我没有给我错误的位置一次。我有它击中超时几次,没有返回任何东西,但除此之外,它工作得很好。我知道这仍然有点老套,我期待有人找到真正的解决方案。

或者,如果你想确保它会一直尝试,直到你想放弃,你可以试试这样的方法。

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

我可能在这里有一些打字和拼写错误,但我希望你能明白。如果有人有问题或者找到更好的建议,请告诉我。

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

我终于找到了firefox, chrome和amp的工作版本;默认导航器在android(仅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);
}
}

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

这已经是一个老问题了,但所有的答案都不能解决我的问题,所以让我们加上我最终找到的那个。它闻起来像一种hack(它确实是一种),但在我的情况下总是有效。对你的处境也抱有希望。

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

感谢每个人的投入,这对我很有帮助。

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

对于开发iPhone应用程序的人来说……

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

如果你不设置它,那么getCurrentPosition将永远不会回调,用户也永远不会被提示。

我在Mozilla遇到了这个问题。所有时间:错误:未知错误获取位置

现在我使用47 Mozilla。我什么方法都试过了,但总是遇到这个问题。然后我在我的地址栏中打开:配置,去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);

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

更多细节参见https://ipinfo.io/developers/replacing-getcurrentposition

传递给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/'的网络位置提供程序:返回错误代码400”。原来谷歌Chrome使用谷歌api在没有内置GPS的设备上获得位置(例如,大多数台式电脑)。谷歌返回基于用户IP地址的大致纬度/经度。然而,在Chrome的开发版本中(如Ubuntu上的Chromium),浏览器版本中不包含API访问密钥。这将导致API请求以静默方式失败。详见铬问题179686:地理定位给予403错误

在2017年,我仍然得到了参差的结果,我有一个理论:API文档说调用现在只在“安全上下文中”可用,即通过HTTPS。我有麻烦得到一个结果在我的开发环境(http在localhost),我相信这就是为什么。

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

我发现,这种方法行不通

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

这种方法非常有效

function storeCoordinates(position) {
console.log(position.coords.latitude, position.coords.longitude);
}


function errorHandler() {...}


navigator.geolocation.getCurrentPosition(storeCoordinates, errorHandler, { enableHighAccuracy: true, timeout: 20000, maximumAge: 0 });

在我们的例子中,它总是第一次工作,但重新运行函数3-4次以上,它就失败了。

简单的解决方法:将其值存储在LocalStorage中。

之前:

navigator.geolocation.getCurrentPosition((position) => {
let val = results[0].address_components[2].long_name;
doSthWithVal(val);
}, (error) => { });

后:

if(localStorage.getItem('getCurrentPosition') !== null) {
doSthWithVal(localStorage.getItem('getCurrentPosition'));
}
else {
navigator.geolocation.getCurrentPosition((position) => {
let val = results[0].address_components[2].long_name;
localStorage.setItem('getCurrentPosition',val);
doSthWithVal(val);
}, (error) => { });
}

我在使用Firefox的响应式设计模式时就遇到过这种情况。已经有一个错误报告文件。现在,在使用地理定位API时不要使用响应式设计模式。

可能对某些人有帮助,在Android上我也有同样的问题,但我通过使用解决了 setTimeout 内部 document.ready 所以这对我来说是有效的,其次,你必须增加超时,以防用户在几秒钟后允许他的位置,所以我把它保持为60000毫秒(1分钟),允许我的成功函数调用,如果用户在1分钟内点击允许按钮

截至2020年年中,这里的答案都没有提供任何解释,只是黑客攻击或猜测。

正如@Coderer在我之前指出的,安全上下文(https)是今天需要的,所以在越来越多的设备上,地理定位在普通http下根本不起作用:

< >强安全上下文 此特性仅在安全上下文中(HTTPS)以及部分或所有支持的浏览器中可用

getCurrentPosition()的第三个参数(以及更适合这里的watchPosition())是PositionOptions对象,由以下属性组成:

  • enableHighAccurancy(默认为false):如果设置为true,响应更慢,更准确。如果你有超时错误,保持这个值为false。如果精度较低,请设置为true。在我的测试中,1秒延迟,1-2米精度,在UMAX平板上没有真假差异。我也在旧的iPhone上测试了5米的震动,如果设置为false。你也可以在GeolocationCoordinates.accurancy属性中测量精度并动态决定。
  • timeout(默认无穷大):在API放弃并调用错误处理程序(第二个参数)之前的毫秒。今天,5秒(5000秒)是合理的,在某些情况下10秒也是合理的。如果您想在地理位置传感器数据不可用时使用B计划,则非常有用。
  • maximumAge(默认0):毫秒当缓存值有效时,设备可能决定使用有效的缓存数据而不是传感器测量。在静态位置设置为无穷大,否则保持为0。

正如@YoLoCo在我之前指出的那样,getCurrentPosition()watchPosition()会干扰,我在2020年确认了他的结果。通常,使用watchPosition代替getCurrentPosition周期性调用。