Javascript navigator.geolocation.getCurrentPosition 有时有效有时无效
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3397585/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
navigator.geolocation.getCurrentPosition sometimes works sometimes doesn't
提问by theassociatedweb
So I have a pretty simple bit of JS using the navigator.geolocation.getCurrentPosition jammy.
所以我有一个使用 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
Basically what's happening here is we get the current position, if it's obtained, two "watermarks" are placed in two fields that say "Current Position" and two hidden fields are created with the lat-long data as their value (they're removed in the beginning so they don't get duplicated every time). There are also two buttons that have a click function tied to them that do the same thing. Unfortunately, every third time or so, it works. What's the problem here???
基本上这里发生的事情是我们获得当前位置,如果获得,两个“水印”被放置在两个显示“当前位置”的字段中,并使用经纬度数据创建两个隐藏字段作为它们的值(它们被删除在开始时,所以它们不会每次都被复制)。还有两个按钮具有与它们相关联的单击功能,可以执行相同的操作。不幸的是,每隔大约三次,它就会起作用。这里有什么问题???
回答by brennanyoung
I have been having exactlythe same problem, and finding almost no information online about it. Nothing at all in the books. Finally I found this sober query on stackoverflow and (ha!) it was the final impetus I needed to set up an account here.
我一直遇到完全相同的问题,并且在网上几乎找不到有关它的信息。书里什么都没有。最后,我在 stackoverflow 上找到了这个清醒的查询,(哈!)这是我在这里设置帐户所需的最后动力。
And I have a partial answer, but alas not a complete one.
我有一个部分的答案,但可惜不是一个完整的答案。
First of all, realise that the default timeoutfor getCurrentPosition is infinite(!). That means that your error handler will never be calledif getCurrentPosition hangs somewhere on the back end.
首先,要意识到getCurrentPosition的默认超时时间是无限的(!)。这意味着如果 getCurrentPosition 挂在后端的某个地方,您的错误处理程序将永远不会被调用。
To ensure that you get a timeout, add the optional third parameter to your call to getCurrentPosition, for example, if you want the user to wait no more than 10 seconds before giving them a clue what is happening, use:
为确保您获得超时,请将可选的第三个参数添加到您对 getCurrentPosition 的调用中,例如,如果您希望用户等待不超过 10 秒才能向他们提供正在发生的事情的线索,请使用:
navigator.geolocation.getCurrentPosition(successCallback,errorCallback,{timeout:10000});
Secondly, I have experienced quite different reliability in different contexts. Here at home, I get a callback within a second or two, although the accuracy is poor.
其次,我在不同的环境中体验到了完全不同的可靠性。在家里,我会在一两秒内收到回调,尽管准确性很差。
At work however, I experience quite bizarre variations in behavior: Geolocation works on some computers all the time (IE excepted, of course), others only work in chrome and safari but not firefox (gecko issue?), others work once, then subsequently fail - and the pattern changes from hour to hour, from day to day. Sometimes you have a 'lucky' computer, sometimes not. Perhaps slaughtering goats at full moon would help?
然而,在工作中,我在行为上遇到了非常奇怪的变化:地理定位一直在某些计算机上工作(当然,IE 除外),其他人只能在 chrome 和 safari 中工作,但不能在 Firefox 中工作(壁虎问题?),其他人工作一次,然后随后失败 - 并且模式每小时都在变化,每天都在变化。有时你有一台“幸运”的电脑,有时没有。也许在满月时宰杀山羊会有所帮助?
I have not been able to fathom this, but I suspect that the back end infrastructure is more uneven than advertisedin the various gung-ho books and websites that are pushing this feature. I really wish that they would be a bit more straight about how flakey this feature is, and how important that timeout setting is, if you want your error handler to work properly.
我一直无法理解这一点,但我怀疑后端基础设施比推动此功能的各种热门书籍和网站中宣传的更不平衡。如果您希望错误处理程序正常工作,我真的希望他们能更直接地了解此功能的重要性,以及超时设置的重要性。
I have been trying to teach this stuff to students today, and had the embarassing situation where my own computer (on the projector and several large screens) was failing silently, whereas about 80% of the students were getting a result almost instantly (using the exact same wireless network). It's very difficult to resolve these issues when my students are also making typos and other gaffes, and when my own pc is also failing.
我今天一直在尝试向学生教授这些东西,遇到了我自己的计算机(在投影仪和几个大屏幕上)无声地失败的尴尬情况,而大约 80% 的学生几乎立即得到了结果(使用完全相同的无线网络)。当我的学生也出现拼写错误和其他失误,以及我自己的电脑也出现故障时,这些问题就很难解决。
Anyway, I hope this helps some of you guys. Thanks for the sanity check!
无论如何,我希望这对你们中的一些人有所帮助。感谢您的健康检查!
回答by going
This is the hacky way that I am getting around this, at least it works in all current browsers (on Windows, I don't own a Mac):
这是我解决这个问题的hacky方式,至少它适用于所有当前浏览器(在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();
}
This will also work if someone clicks the close or chooses no or chooses the Never Share option on Firefox.
如果有人在 Firefox 上单击关闭或选择否或选择从不共享选项,这也将起作用。
Clunky, but it works.
笨重,但它的工作原理。
回答by K'shin Gendron
This works for me every time:
这每次都对我有用:
navigator.geolocation.getCurrentPosition(getCoor, errorCoor, {maximumAge:60000, timeout:5000, enableHighAccuracy:true});
Though it isn't very accurate. The funny thing is that on the same device if I run this it puts me off about 100 meters (every time), but if I go to google's maps it finds my location exactly. So although I think the enableHighAccuracy: true helps it to work consistently, it doesn't seem to make it any more accurate...
虽然不是很准确。有趣的是,在同一台设备上,如果我运行它,它会让我离开大约 100 米(每次),但是如果我去谷歌的地图,它会准确地找到我的位置。因此,尽管我认为 enableHighAccuracy: true 有助于它始终如一地工作,但它似乎并没有使它更准确......
回答by Niels Steenbeek
This is already an old question, but all answers didn't solve my problem, so let's add the one I finally found. It smells like a hack (and it is one), but works always in my situation. Hope in your situation too.
这已经是一个老问题了,但是所有的答案都没有解决我的问题,所以让我们添加我最终找到的一个。它闻起来像一个黑客(它是一个),但在我的情况下总是有效。希望你的情况也一样。
//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
});
回答by mvilrokx
Same here people, this works perfect btw in Chrome (stable, dev and canary) just not in FF and Safari. It also works perfect on my iPhone and iPad (Safari!). This might be due to the relative newness of this feature (i.e. it is a bug). I spend almost a week on this now and I just cannot get it to work on those browsers
同样在这里的人,顺便说一句,这在 Chrome(稳定版、开发版和 Canary 版)中非常有效,只是在 FF 和 Safari 中无效。它也适用于我的 iPhone 和 iPad(Safari!)。这可能是由于此功能相对较新(即它是一个错误)。我现在花了将近一个星期的时间,但我无法让它在那些浏览器上运行
Here's what I found:
这是我发现的:
The first time you call getCurrentPosition it works perfect. Any subsequent call never returns, i.e. it does not fire the successCallback or the errorCallback functions. I added a few position options to my call to prove my point:
第一次调用 getCurrentPosition 时,它工作得很好。任何后续调用都不会返回,即它不会触发 successCallback 或 errorCallback 函数。我在电话中添加了一些头寸选项来证明我的观点:
navigator.geolocation.getCurrentPosition(successCallback, errorCallback, {timeout: 10000});
and it times out every time (after the first successful call). I thought I could fix it with maximumAge, but that doesn't seem to be working as it is suppose to work either:
并且每次都超时(在第一次成功调用之后)。我以为我可以用maximumAge修复它,但这似乎不起作用,因为它也应该起作用:
navigator.geolocation.getCurrentPosition(successCallback, errorCallback, {maximumAge:60000, timeout: 2000});
this should prevent actually calling the getCurrentPosition function if you call it within 60 seconds, but it ignores this (however, this could be due because I actually refresh my page to trigger the second call, not sure if this is persistent accross calls)
如果您在 60 秒内调用它,这应该会阻止实际调用 getCurrentPosition 函数,但它会忽略这一点(但是,这可能是因为我实际上刷新了我的页面以触发第二次调用,不确定这是否是持续的跨调用)
btw, even google's examplesfail on these browsers which leads me to believe that this are indeed browser bugs, try it, load it twice in Safari and it won't work the second time.
顺便说一句,即使谷歌的例子在这些浏览器上也失败了,这让我相信这确实是浏览器的错误,试试看,在 Safari 中加载两次,第二次就不行了。
If anybody finds a solution for this, PLEASE let me know :-)
如果有人为此找到解决方案,请告诉我:-)
Cheers.
干杯。
回答by Mark Baijens
You don't get an error message because it has no timeout by default (At least i think). I have had the same problem with firefox only for me firefox always gives an timeout. You can set a timeout yourself like this.
您不会收到错误消息,因为默认情况下它没有超时(至少我认为)。我在 firefox 上遇到了同样的问题,只对我来说 firefox 总是超时。您可以像这样自己设置超时。
My function works great in chrome but i get a timeout everytime in firefox.
我的功能在 chrome 中运行良好,但我每次在 Firefox 中都会超时。
navigator.geolocation.getCurrentPosition(
function(position) {
//do succes handling
},
function errorCallback(error) {
//do error handling
},
{
timeout:5000
}
);
I recommend to watch your errors carefully. Be expected for everything. Have a backup plan for everything. I use some default values or values from my database myself in case both google geolocations and navigator geolocations fails.
我建议仔细观察你的错误。一切都值得期待。为所有事情制定备份计划。我自己使用数据库中的一些默认值或值,以防 google geolocations 和 navigator geolocations 都失败。
回答by Coderer
I'm still getting spotty results in 2017, and I have a theory: the API documentationsays that the call is now only available "in a secure context", i.e. over HTTPS. I'm having trouble getting a result in my development environment (http on localhost) and I believe this is why.
我在 2017 年的结果仍然参差不齐,我有一个理论:API 文档说该调用现在只能在“安全上下文”中使用,即通过 HTTPS。我在我的开发环境(本地主机上的 http)中无法获得结果,我相信这就是原因。
回答by JoLoCo
I'll post this here in case it's useful to anyone…
我会把这个贴在这里,以防它对任何人有用……
On iOS Safari, calls to navigator.geolocation.getCurrentPositionwould timeout if I had an active navigator.geolocation.watchPositionfunction running.
在 iOS Safari 上,navigator.geolocation.getCurrentPosition如果我有一个活动navigator.geolocation.watchPosition函数正在运行,对 的调用会超时。
Starting and stopping the watchPositionproperly using clearWatch()as described here, worked: https://developer.mozilla.org/en-US/docs/Web/API/Geolocation/watchPosition
按照此处所述启动和停止watchPosition正确使用clearWatch(),有效:https: //developer.mozilla.org/en-US/docs/Web/API/Geolocation/watchPosition
回答by Drew Calder
So I was running into the same thing. I tried the timeout solution which worked but not reliably. I found that if you just call it twice the location is refreshed properly
所以我遇到了同样的事情。我尝试了有效但不可靠的超时解决方案。我发现如果你只调用它两次,位置就会正确刷新
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;
}
this of course is a little slower but I have not had it give me the wrong position once. I have had it hit the timeout a few times and not return anything but other then that it works great. I know this is still a little hacky and I am looking forward to someone finding the real solution.
这当然有点慢,但我没有让它给我一次错误的位置。我已经让它超时几次并且没有返回任何东西,但除此之外它工作得很好。我知道这仍然有点hacky,我期待有人找到真正的解决方案。
Or if you want to make sure it is going to keep trying until you want to give up you could try something like this.
或者,如果你想确保它会一直尝试直到你想放弃,你可以尝试这样的事情。
//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}
)
}
}
I probably have some typeos and some spelling errors in here but I hope you get the idea. Let me know if anyone has questions or if someone finds something better.
我这里可能有一些字体和拼写错误,但我希望你能明白。如果有人有问题或有人找到更好的东西,请告诉我。
回答by jbdemonte
here is my solution thanks to a closure :
由于关闭,这是我的解决方案:
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);

