navigator.geolocation.getCurrentPosition 有时有效有时无效
所以我使用 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
基本上,这里发生的事情是我们获得当前位置,如果获得了,两个“水印”被放置在两个表示“当前位置”的字段中,并且使用经纬度数据作为其值创建两个隐藏字段(它们被删除)在开始时这样它们就不会每次都重复)。还有两个按钮具有与其关联的单击功能,可以执行相同的操作。 不幸的是,每隔三次左右,它就会起作用。 这里有什么问题???
So I have a pretty simple bit of JS using the 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
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???
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(24)
我有一个部分答案,但可惜不是完整的答案。
首先,要意识到 getCurrentPosition 的默认超时是无限(!)。这意味着如果 getCurrentPosition 挂在后端的某个位置,您的错误处理程序将永远不会被调用。
为了确保超时,请将可选的第三个参数添加到对 getCurrentPosition 的调用中,例如,如果您希望用户等待不超过 10 秒,然后再向他们提供正在发生的情况的线索,请使用:
其次,我经历过不同情况下的可靠性有很大不同。在家里,我会在一两秒内收到回电,尽管准确性很差。
然而,在工作中,我经历了相当奇怪的行为变化:地理定位在某些计算机上一直有效(当然 IE 除外),其他计算机只能在 chrome 和 safari 中工作,但不能在 Firefox 中工作(壁虎问题?),其他计算机只能工作一次,然后随后工作失败——而且模式每小时、每天都在变化。有时您有一台“幸运”的计算机,有时则没有。也许在满月时宰杀山羊会有帮助?
我无法理解这一点,但我怀疑后端基础设施比在各种推动此功能的热衷书籍和网站中宣传的更不平衡。我真的希望他们能更直接地说明这个功能有多么不稳定,以及如果您希望错误处理程序正常工作,超时设置有多重要。
今天我一直在尝试向学生教授这些内容,但遇到了尴尬的情况:我自己的计算机(在投影仪和几个大屏幕上)无声无息地出现故障,而大约 80% 的学生几乎立即就得到了结果(使用完全相同的无线网络)。当我的学生也犯错别字和其他错误,而我自己的电脑也出现故障时,解决这些问题非常困难。
I have a partial answer, but alas not a complete one.
First of all, realise that the default timeout for getCurrentPosition is infinite(!). That means that your error handler will never be called if getCurrentPosition hangs somewhere on the back end.
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:
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?
I have not been able to fathom this, but I suspect that the back end infrastructure is more uneven than advertised in 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.
这是我解决这个问题的一种hacky方法,至少它适用于所有当前的浏览器(在Windows上,我没有Mac):
如果有人单击“关闭”或选择“否”或选择“从不共享”,这也将起作用Firefox 上的选项。
笨重,但它有效。
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):
This will also work if someone clicks the close or chooses no or chooses the Never Share option on Firefox.
Clunky, but it works.
这每次都对我有用:
尽管它不是很准确。有趣的是,在同一台设备上,如果我运行这个,它会让我偏离大约 100 米(每次),但如果我去谷歌地图,它会准确地找到我的位置。因此,尽管我认为enableHighAccuracy:true有助于它一致地工作,但它似乎并没有使它变得更准确......
This works for me every time:
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...
这已经是一个老问题了,但是所有答案都没有解决我的问题,所以让我们添加我最终找到的答案。它闻起来像一个黑客(它确实是一个),但在我的情况下总是有效。希望你的情况也一样。
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.
同样的人,这在 Chrome(稳定版、开发版和金丝雀版)中工作得很好,只是在 FF 和 Safari 中不行。它在我的 iPhone 和 iPad(Safari!)上也能完美运行。这可能是由于该功能相对较新(即它是一个错误)。我现在花了将近一周的时间,但我无法让它在这些浏览器上工作。
这是我发现的:
第一次调用 getCurrentPosition 时,它工作得非常完美。任何后续调用都不会返回,即它不会触发 successCallback 或 errorCallback 函数。我在通话中添加了一些位置选项来证明我的观点:
每次都会超时(在第一次成功通话后)。我以为我可以用 MaximumAge 修复它,但这似乎并没有像它想象的那样工作:
如果您在 60 秒内调用 getCurrentPosition 函数,这应该会阻止实际调用 getCurrentPosition 函数,但它会忽略这一点(但是,这可能是因为我实际上刷新了页面以触发第二个调用,不确定这是否是跨调用的持久性)
顺便说一句,甚至google 的示例 在这些浏览器上失败,这让我相信这确实是浏览器错误,尝试一下,在 Safari 中加载两次,但它不起作用第二次。
如果有人找到解决方案,请告诉我:-)
干杯。
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
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:
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:
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)
btw, even google's examples fail 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.
If anybody finds a solution for this, PLEASE let me know :-)
Cheers.
您不会收到错误消息,因为默认情况下它没有超时(至少我认为)。我在 Firefox 中也遇到过同样的问题,只是对我来说,Firefox 总是超时。您可以像这样自己设置超时。
我的函数在 Chrome 中运行良好,但在 Firefox 中每次都会超时。
我建议仔细观察你的错误。对一切都抱有期待。为所有事情制定一个备份计划。我自己使用一些默认值或数据库中的值,以防谷歌地理位置和导航器地理位置失败。
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.
My function works great in chrome but i get a timeout everytime in firefox.
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.
我会将其发布在这里,以防它对任何人有用...
在 iOS Safari 上,如果我有一个活动的
navigator.geolocation.watchPosition
,对navigator.geolocation.getCurrentPosition
的调用将会超时功能运行。按照此处所述使用
clearWatch()
正确启动和停止watchPosition
有效:https://developer.mozilla.org/en-US/docs/Web/API/Geolocation/watchPositionI'll post this here in case it's useful to anyone…
On iOS Safari, calls to
navigator.geolocation.getCurrentPosition
would timeout if I had an activenavigator.geolocation.watchPosition
function running.Starting and stopping the
watchPosition
properly usingclearWatch()
as described here, worked: https://developer.mozilla.org/en-US/docs/Web/API/Geolocation/watchPosition2017 年我的结果仍然参差不齐,我有一个理论: API 文档 表示该调用现在只能“在安全上下文中”使用,即通过 HTTPS。我在我的开发环境(本地主机上的 http)中无法获得结果,我相信这就是原因。
I'm still getting spotty results in 2017, and I have a theory: the API documentation says 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.
这是我的解决方案,感谢闭包:
here is my solution thanks to a closure :
截至 2020 年中期,这里的答案都没有提供任何解释,只是黑客攻击或猜测。
正如 @Coderer 在我之前指出的那样,如今需要安全上下文 (https),因此在越来越多的设备上,地理定位根本无法使用纯 http:
getCurrentPosition()
的第三个参数(以及更适合这里的watchPosition()
)是 PositionOptions 对象包含以下属性:enableHighAccurancy
(默认 false):如果设置为 true,响应速度会变慢,并且更准确。如果出现超时错误,请将其保留为 false。如果精度较低,请将其设置为 true。在我的测试中,准确度有所不同,并且在某些设备上有没有效果。在其他设备上设置 true 可能会导致电池电量消耗得惊人地快。timeout
(默认无穷大):API 放弃并调用错误处理程序之前的毫秒数(第二个参数)。如今,大多数启用了地理定位并授予浏览器/页面权限的移动设备都会在一秒钟内以合理的精度获取该值。当地理定位服务不可用时,可以使用geo IP等替代方法,延迟可能会很多秒,并且精度通常从有问题到无用。maximumAge
(默认 0):缓存值有效时的毫秒数,设备可能决定使用有效的缓存数据而不是传感器测量。我通常使用缓慢移动的设备(例如带着手机行走)将其设置为非零值。在静态设备上,可以设置 Infinity 以避免随之而来的读取错误。正如 @YoLoCo 在我之前指出的那样,
getCurrentPosition()
和watchPosition()
会产生干扰,我在 2020 年确认了他的结果。通常,使用 watchPosition 而不是 getCurrentPosition 定期调用。As of mid 2020, none of the answers here provides any explanation, just hacking or guessing.
As @Coderer points out before me, secure context (https) is required today, so on more and more devices geolocation doesn't work at all with plain http:
The third parameter of
getCurrentPosition()
(andwatchPosition()
which is more suitable here) is PositionOptions object consisting of these properties:enableHighAccurancy
(default false): if set to true, response is slower and more accurate. If you got timeout errors, keep this to false. If the accurancy is low, set it to true. In my tests the accurancy varies and on some devices it has no effect. On other devices setting true may cause surprisingly quick battery depletion.timeout
(default infinity): milliseconds before the API gives up and calls the error handler (the second parameter). Today most mobile devices with geolocation enabled and permission granted for the browser/page get the value with reasonable accurancy within a second. When the geolocation service is not available, alternative method like geo IP may be used, the delay can be many seconds and the precision usually ranges from questionable to useless.maximumAge
(default 0): milliseconds when cached value is valid, the device may decide to use valid cached data instead of sensor measure. I usually set this to non-zero values with slowly moving devices (like walking with mobile phone). On static devices, Infinity can be set to avoid consequent reading errors.As @YoLoCo points out before me,
getCurrentPosition()
andwatchPosition()
interferes and I confirm his results in 2020. Generally, use watchPosition instead of getCurrentPosition periodical calls.所以我遇到了同样的事情。我尝试了超时解决方案,该解决方案有效但不可靠。我发现如果你只调用它两次,位置就会正确刷新,
这当然会慢一点,但我还没有让它给我一次错误的位置。我已经让它超时了几次并且没有返回任何东西,但除此之外它工作得很好。我知道这仍然有点棘手,我期待有人找到真正的解决方案。
或者,如果你想确保它会继续尝试,直到你想放弃,你可以尝试这样的事情。
我这里可能有一些打字错误和拼写错误,但我希望你能明白。如果有人有疑问或者有人找到更好的东西,请告诉我。
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
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.
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.
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.
对于任何使用 iPhone 应用程序的人...
如果您的代码在 iOS 9+ 上的 UIWebView 中运行,则必须在应用程序的 plist 中设置
NSLocationWhenInUseUsageDescription
。如果您不设置它,则
getCurrentPosition
将永远不会回调,也永远不会提示用户。For anyone working on an iPhone app...
If your code is running in a UIWebView on iOS 9+, then you must set
NSLocationWhenInUseUsageDescription
within your app's plist.If you don't set it then
getCurrentPosition
will never call back and the user will never be prompted.第二个参数传递给
Geolocation.getCurrentPosition()
是您要处理任何地理位置错误的函数。错误处理函数本身接收
PositionError
对象,其中包含有关地理定位尝试失败原因的详细信息。如果您有任何问题,我建议将错误输出到控制台:在我的代码中执行此操作会显示消息“网络位置提供程序位于 ' https://www.googleapis.com/':返回错误代码 400”。事实证明,Google Chrome 使用 Google API 在没有内置 GPS 的设备(例如,大多数台式计算机)上获取位置。 Google 根据用户的 IP 地址返回大致的纬度/经度。 但是,在 Chrome 的开发人员版本(例如 Ubuntu 上的 Chromium)中,浏览器版本中不包含 API 访问密钥。这会导致 API 请求静默失败。有关详细信息,请参阅 Chromium 问题 179686:地理位置给出 403 错误。
The second parameter passed to
Geolocation.getCurrentPosition()
is the function you want to handle any geolocation errors. The error handler function itself receives aPositionError
object with details about why the geolocation attempt failed. I recommend outputting the error to the console if you have any issues:Doing this in my code revealed the message "Network location provider at 'https://www.googleapis.com/' : Returned error code 400". Turns out Google Chrome uses the Google APIs to get a location on devices that don't have GPS built in (for example, most desktop computers). Google returns an approximate latitude/longitude based on the user's IP address. However, in developer builds of Chrome (such as Chromium on Ubuntu) there is no API access key included in the browser build. This causes the API request to fail silently. See Chromium Issue 179686: Geolocation giving 403 error for details.
我一直遇到类似的问题,并且一直在研究浏览器对调用 getCurrentPosition 的频率是否有限制的可能性。似乎我经常可以获取位置,但如果我立即刷新页面,就会超时。如果我稍等一下,通常可以再次找到位置。这通常发生在 FF 上。在 Chrome 和 Safari 中,我还没有注意到 getCurrentPosition 超时。只是一个想法......
虽然我找不到任何文档来支持这一点,但这是我经过多次测试后得出的结论。也许其他人有一些相关信息?
I have been having similar issues, and have been looking into the possibility that browsers have limits on how often getCurrentPosition can be called. It seems I can often get a location, but if i refresh the page right away it will time out. If I wait for a bit, I can usually get a location again. This usually happens with FF. In Chrome and Safari, I have not yet noticed getCurrentPosition timing out. Just a thought...
Although I cannot find any documentation to support this, it was a conclusion I came to after much testing. Perhaps someone else has has some info about that?
我终于找到了 Firefox、Chrome 和 Chrome 的工作版本。 android 中的默认导航器(仅测试 4.2):
I finally found a working version for firefox, chrome & default navigator in android (4.2 tested only):
我在 Mozilla 中遇到这个问题。始终:错误:获取位置时发生未知错误。
现在我使用的是 47 Mozilla。我已经尝试了一切,但一直都是这个问题。 但是然后我在地址栏中打开about:config,转到geo.wifi.ui并将其值更改为“https://location.services.mozilla.com/v1/geolocate?key=test" 。作品!
如果您出现位置获取超时错误,请尝试增加超时值:
I have this problem in Mozilla. All time: Error: Unknown error acquiring position.
Now i'm using 47 Mozilla. I have tried everything, but all time this problem. BUT then i open about:config in my addsress bar, go geo.wifi.ui and changed it value to "https://location.services.mozilla.com/v1/geolocate?key=test". works!
If u have Position acquisition timed out error, try to increase timeout value:
我发现,这种方式行不通
但是
这种方式工作完美
I found, that this way doesn't work
But
this way works perfect
@brennanyoung 的回答很好,但如果您想知道在失败的情况下该怎么做,您可以使用 IP 地理定位 API,例如 https: //ipinfo.io(这是我的服务)。下面是一个示例:
请参阅 https://ipinfo.io/developers/replacing-getcurrentposition 了解更多信息细节。
@brennanyoung's answer is great, but if you're wondering what to do in the failure case you could use an IP geolocation API such as https://ipinfo.io (which is my service). Here's an example:
See https://ipinfo.io/developers/replacing-getcurrentposition for more details.
在我们的例子中,它第一次总是有效,但重新运行该函数超过 3-4 次,它就会失败。
简单的解决方法:将其值存储在 LocalStorage 中。
之前:
之后:
In our case it always works the first time but rerunning the function more than 3-4 times, it fails.
Simple workaround: Store it's value in LocalStorage.
Before:
After:
我最近自己注意到了这个问题,我不确定它是如何发生的,但有时 Firefox 会卡在缓存中加载的某些内容上。清除缓存并重新启动 Firefox 后,它似乎可以再次运行。
I noticed this problem recently myself, and I'm not sure how it comes about but it would appear sometimes firefox gets stuck on something loaded in cache. After clearing cache and restarting firefox it appears to function again.
感谢大家的意见,这对我很有帮助。
除了必须使用 watchPosition() 而不是 getCurrentPosition() 之外,我还发现我需要将调用从 document.ready() 中移至头部。
Thanks to everyone for their input, this helped me.
In addition to having to use watchPosition() instead of getCurrentPosition(), I also found that I needed to move the call from within document.ready() to the head.
我在使用 Firefox 的响应式设计模式时就遇到过这种情况。已提交错误报告。目前,在使用 Geolocation API 时不要使用响应式设计模式。
This happened to me when using Firefox's responsive design mode. There has been a bug report filed. For now, just don't use responsive design mode while using the Geolocation API.
可能它对某些人有帮助,在 Android 上我遇到了同样的问题,但我通过使用解决了这个问题
设置超时
里面
文档准备就绪
所以它对我有用其次你必须增加超时以防万一用户在几秒钟后允许他的位置,所以我将其保持为 60000 毫秒(1 分钟),允许如果用户在 1 分钟内单击允许按钮则调用我的成功函数。
May be it helps some one, On Android i had same issue but i figured it out by using
setTimeout
inside
document.ready
so it worked for me secondly you have to increase the timeout just incase if user allow his location after few seconds, so i kept it to 60000 mili seconds (1 minute) allowing my success function to call if user click on allow button within 1 minute.
此库为地理定位调用添加了desiredAccuracy和maxWait选项,这意味着它将继续尝试获取位置,直到精度在指定范围内。
This library adds a desiredAccuracy and maxWait option to geolocation calls, which means it will keep trying to get a position until the accuracy is within a specified range.