navigator.geolocation.getCurrentPositionが機能する場合と機能しない場合がある


220

だから私は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

基本的にここで起こっていることは、現在の位置を取得することです。取得すると、「現在の位置」という2つのフィールドに2つの「透かし」が配置され、緯度と経度のデータを値として2つの非表示フィールドが作成されます(これらは削除されます)最初は、毎回複製されることがないように)。同じことを行うクリック機能が関連付けられた2つのボタンもあります。残念ながら、3回おきに動作します。ここの問題は何ですか???


使用する前に関数を定義してください。
tcooc 2010

4
@ digitalFresh、JSパーサーはコードが実行を開始する前にこれらの宣言を探すため、問題はありません
antimatter15

そこでjQueryの使用が問題を引き起こしている可能性はありますか?
Web

1
時々機能しないと言うとき、正確にはどういう意味ですか?されるnoLocation関数が呼び出されていますか?もしそうなら、あなたは追加することができますerrorにパラメータをnoLocation()して、error.codeそしてerror.messageデバッグに役立つことがあります。また、使用しているブラウザーや、異なるブラウザーで同じ問題が発生するかどうかを確認するのにも役立ちます。
npdoty 2010

つまり、それは時々私に緯度経度を与えます、そして時にはそれはそうしません。機能しない場合は、「場所が見つかりませんでした」というメッセージもスローされないため、noLocationビットも発生しません。
theassociatedweb

回答:


342

私はまったく同じ問題を抱えており、それに関するオンラインの情報はほとんど見つかりません。本にはまったく何もありません。最後に、この落ち着いたクエリがstackoverflowで見つかりました(これが、ここでアカウントを設定するために必要な最後の原動力です)。

そして、私は部分的な答えを持っていますが、残念ながら完全なものではありません。

まず、getCurrentPosition のデフォルトのタイムアウト無限(!)であることを理解してください。つまり、getCurrentPositionがバックエンドのどこかでハングした場合、エラーハンドラーは呼び出されません。

タイムアウトを確実に取得するには、オプションの3番目のパラメーターをgetCurrentPositionへの呼び出しに追加します。たとえば、ユーザーに何が起こっているのか手がかりを与える前に10秒以上待たせたくない場合は、以下を使用します。

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

第二に、私はさまざまな状況でまったく異なる信頼性を経験しました。ここ自宅では、1、2秒以内にコールバックが返されますが、精度は低くなります。

ただし、職場ではかなり奇妙な動作の変化が発生します。ジオロケーションは常に一部のコンピューターで動作し(もちろんIEを除く)、ChromeとSafariでのみ動作し、Firefoxでは動作しません(Geckoの問題?)。失敗-パターンは時間ごとに、日ごとに変化します。「ラッキー」なコンピューターを持っていることもあれば、持っていないこともあります。おそらく満月でヤギを屠殺することは役立つでしょうか?

これを理解することはできませんでしたが、バックエンドのインフラストラクチャは宣伝されているよりも不均一であると思います、この機能を推進しているさまざまなガンホーの本やウェブサイトでれていると思います。エラーハンドラーを適切に動作させたい場合は、この機能がいかに不安定で、タイムアウト設定がどれほど重要であるかについて、彼らがもう少し真っ直ぐであることを本当に望みます

私は今日、このことを学生に教えようとしており、自分のコンピューター(プロジェクターといくつかの大きな画面)が静かに失敗するという恥ずかしい状況がありましたが、学生の約80%はほぼ瞬時に結果を取得していました(まったく同じワイヤレスネットワーク)。生徒たちがタイプミスや他の不快感を与えている場合や、自分のPCも失敗している場合は、これらの問題を解決するのは非常に困難です。

とにかく、これがあなたたちの一部に役立つことを願っています。健全性チェックをありがとう!


5
良い詳細な情報、ありがとう!同じ問題が発生していますが、Firefox 3.6.13でのみ発生します。Chromeはかなり信頼できるようです。
フェリペ・リマ

ここでも同じで、maximumAgeパラメータも信頼性が低いようです。投稿ありがとうございます。
Richard

1
いいですね、同じ問題が発生しました(Samsung Galaxy Tab、10.1、Android 4.0.3を実行)。上記のタイムアウトパラメータを使用すると、問題を処理できました。
mlo55 2013

9
timeoutオプションのgetCurrentPosition()実際のタイミングを理解することが重要です。ユーザーが地理位置情報要求を許可または拒否する時間ではありませんが、許可が付与されてからネットワークが位置情報を返すまでにかかる時間を許可します。ユーザーが位置情報要求に応答しない場合、エラーハンドラーは呼び出されません。したがって、@ xiaohouzi79の回答のように、2番目のタイムアウトが必要です。
フランソワ

2
満月で山羊を屠殺することは役立つでしょうか?LOL
Asim KT

66

これは私がこれを回避しているハックな方法です、少なくとも現在のすべてのブラウザで動作します(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で[共有しない]オプションを選択した場合にも機能します。

不格好ですが、機能します。


1
+1しかし、geolocFail();エラーハンドラとジオコーダーがありませんgetcodeLatLng();
カイザー

甘い-誰かが場所を共有しないことを選択した場合、タイマーは美しく機能します。一部のブラウザは、ユーザーがこれを行うとうまく動作しません。このタイマーの回避策は、Store Locator Plus WPプラグインでうまく機能しました。
ランスクリーブランド

2
@sajith-このソリューションが最近のFFブラウザーで古くなっているかどうかはわかりません。私が作業しているサイトに必要だったため、ソリューションを提供したときに機能しました。テストしましたか?
行く

申し訳ありませんが、それは....私はそれがwork.After閉じて作るものを見つけるとあなたの解決のためにFFその作業........ありがとうを再開カントworked.But
sajith

1
文字列内で関数を使用しないでください。悪の評価は不必要にそこで働いています。setTimeout( "geolocFail()"、10000);
atilkan 2017

42

これはいつも私にとってうまくいきます:

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

正確ではありませんが。面白いのは、同じデバイスでこれを実行すると、約100メートル(毎回)離れるということですが、Googleのマップに移動すると、自分の位置が正確にわかります。したがって、私はenableHighAccuracy:trueが一貫して機能するのに役立つと思いますが、それはそれをより正確にするようには見えません...


これにより、Firefoxがリクエストを拒否し、タイムアウトオブジェクトを送り返すことができなくなりました。
トニー

100メートル離れたところにある基地局があります。つまり、携帯電話ではなく、基地局の場所が返されます。私がgpsをキックするために外にいた場合、より正確になる可能性があります
。– K'shin Gendron、2015

9
maximumAgeパラメーターが60秒に設定されているため、数メートル離れてしまいます。つまり、60秒前の場所に場所を置くことができます。maximumAgeを10秒以下(maximumAge:10000)に設定して、再試行してください。
ロバート・スミス

Observableを返すAngular Resolver内でこのgetCurrentPositionを使用していました。リゾルバーは断続的にのみ完了しました。これらのオプションを追加すると、{maximumAge:60000、timeout:5000、enableHighAccuracy:true}で毎回機能します!!!
Moutono

17

これはすでに古い質問ですが、すべての回答で問題が解決しなかったので、最後に見つけた質問を追加してみましょう。それはハックのように臭いがします(それは1つです)が、私の状況では常に機能します。あなたの状況にも願っています。

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

3
それが最もハックのハックであり、あなたがどうやってそれを試そうと思ったかさえわからないが、それは私の問題を解決する。ありがとうございました!
Brett Gregson 2016年

自分でこれを使用する場合もあります。私の経験では、2番目の試みは常により効果的です
Nico Westerdale

13

ここの人々と同じように、これはFFや​​Safariではなく、Chrome(stable、dev、canary)で完璧に機能します。iPhoneやiPad(Safari!)でも完璧に動作します。これは、この機能が比較的新しいためである可能性があります(つまり、バグです)。私はこれにほぼ1週間費やしていますが、それらのブラウザーで動作させることができません

これが私が見つけたものです:

getCurrentPositionを初めて呼び出すと、完全に機能します。後続の呼び出しは決して戻りません。つまり、successCallback関数またはerrorCallback関数を起動しません。自分の要点を証明するために、いくつかのポジションオプションをコールに追加しました。

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

そしてそれは毎回タイムアウトします(最初の呼び出しが成功した後)。maximumAgeで修正できると思いましたが、次のいずれかで機能することが想定されているため、機能していないようです。

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

これにより、60秒以内にgetCurrentPosition関数を実際に呼び出すことはできなくなりますが、これは無視されます(ただし、実際にページを更新して2番目の呼び出しをトリガーするため、これが原因である可能性があります。

ところで、グーグルの例もこれらのブラウザで失敗するので、これは確かにブラウザのバグであると思い込み、試してみて、Safariで2回ロードすると、2回目には機能しません。

誰かがこれに対する解決策を見つけた場合は、私に知らせてください:-)

乾杯。


私はあなたと同じ問題を抱えています、それは最初の呼び出しでは機能しますが、次の呼び出しでは機能しませんが、誰かが解決策を見つけたら、私は非常に興味をそそられます... )
アドリアーノリッツォ

8

デフォルトではタイムアウトがないため、エラーメッセージは表示されません(少なくとも私はそう思います)。私はFirefoxで同じ問題を抱えていましたが、Firefoxは常にタイムアウトを与えます。このように自分でタイムアウトを設定できます。

私の機能はChromeでうまく機能しますが、Firefoxでは毎回タイムアウトになります。

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

エラーを注意深く監視することをお勧めします。すべてに期待してください。すべてのバックアップ計画を立てます。Googleジオロケーションとナビゲータージオロケーションの両方が失敗した場合に備えて、いくつかのデフォルト値または自分のデータベースの値を自分で使用しています。


7
参考までに、maximumAgeはキャッシュ内の位置データの経過時間を参照し、無限に設定すると、キャッシュされたバージョンが取得されることが保証されます。これを0に設定すると、デバイスは強制的に位置を取得します。
Porco

maximumAge:Infinityは上で指摘したように失敗するため、反対投票されました。これは、キャッシュされた値を強制的に使用することを意味します。
n13

7

2017年でもまだむらのある結果が出ており、理論があります。APIドキュメントには、呼び出しは「安全なコンテキスト」で、つまりHTTPS経由でのみ利用できるようになっているとあります。開発環境(localhost上のhttp)で結果を取得するのに問題があり、これが理由だと思います。


面白いですね。2020年でさえ、localhost上のHTTPSでまだ不安定です!
NitroStoutPlz

6

誰かに役立つ場合に備えて、ここに投稿します…

iOS Safariではnavigator.geolocation.getCurrentPosition、アクティブな場合、への呼び出しがタイムアウトしますnavigator.geolocation.watchPosition関数を実行します。

ここで説明さwatchPositionれてclearWatch()いるように適切に使用して開始および停止すると、https//developer.mozilla.org/en-US/docs/Web/API/Geolocation/watchPosition


1
どうもありがとうございます。これが私の解決策でした。
秦正泉

5

ここに閉鎖のおかげで私の解決策があります:

  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 && navigator.geolocation
Ashish Singh Rawat

5

だから私は同じ事に遭遇していました。私はうまくいったが確実ではないタイムアウトソリューションを試しました。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;
}

もちろんこれは少し遅いですが、一度間違った位置を与えることはありませんでした。私はそれが数回タイムアウトに達して何も返さないようにしましたが、それ以外はそれが素晴らしい働きをすることはありません。これはまだ少しハックであり、本当の解決策を見つける誰かを楽しみにしています。

または、あきらめたくなるまで試してみることを確認したい場合は、次のような方法を試してください。

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

私はおそらくここにいくつかのタイプミスといくつかのスペルミスがありますが、あなたがアイデアを得ることを願っています。誰かに質問があるか、誰かがより良い何かを見つけたかどうか私に知らせてください。


4

iPhoneアプリで作業している人のために...

コードがiOS 9以降のUIWebViewで実行されている場合は、設定する必要があります NSLocationWhenInUseUsageDescription、アプリのplist内であります。

設定しないgetCurrentPositionと、コールバックが行われず、ユーザーにプロンプ​​トが表示されることはありません。


3

この方法は機能しないことがわかりました

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

4
両方の違いは何ですか?
Pardeep Jain

匿名関数vs名前付き関数
1nstinct '

本当に大きな違い。ありがとう、これも機能しない
なし

3

@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を参照してください。


:ここでは、このための修正リンクですipinfo.io/developers/replacing-getcurrentposition
peater

5
ひどい。精度は、米国とカナダでは実際の位置から5〜7マイル離れたところにあり、ロシアのどこかでは100マイル離れています。
ekashking

1
多くのアプリケーションで問題ありません-場所がわからないよりずっと良いです。
ベンダウリング

これはどこでも機能しません。すべてのリクエストで経度と緯度が間違っている
なし

どういう意味ですか?例はありますか?
ベンダウリング

2

私は同様の問題を抱えており、ブラウザがgetCurrentPositionを呼び出すことができる頻度に制限がある可能性を調査しています。よく場所を取得できるようですが、ページをすぐに更新するとタイムアウトします。少し待つと、通常は場所を再取得できます。これは通常、FFで発生します。ChromeとSafariでは、getCurrentPositionのタイムアウトにまだ気付いていません。ちょっとした考え...

これをサポートするドキュメントは見つかりませんでしたが、多くのテストの結果、結論に達しました。おそらく他の誰かがそれについていくつかの情報を持っていますか?


それは良い点です。タイムアウト/失敗は、主にテストを行って地理位置情報データを繰り返しクエリしているときに発生するようです。これがバグの結果なのか、それとも仕様によるものなのかを知りたいのですが。
ジェイミー

ブラウザが位置情報サービスへの通話量を制限するようなケースは見たことがありません。クエリの頻度はどれくらいですか?
Nico Westerdale

2

私はようやく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

渡される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/ ':返されたエラーコード400」というメッセージが表示されました。Google Chromeは、Google APIを使用して、GPSが組み込まれていないデバイス(たとえば、ほとんどのデスクトップコンピューター)で位置を取得することがわかりました。Googleは、ユーザーのIPアドレスに基づいておおよその緯度/経度を返します。ただし、Chromeのデベロッパービルド(UbuntuのChromiumなど)では、ブラウザビルドにAPIアクセスキーは含まれていません。これにより、APIリクエストが通知なしで失敗します。詳細については、Chromium問題179686:ジオロケーションにより403エラーが発生するをご覧ください。


1

私はMozillaでこの問題を抱えています。常に:エラー:位置の取得中に不明なエラーが発生しました

現在、47 Mozillaを使用しています。私はすべてを試しましたが、いつもこの問題です。しかしその後、私は開くabout:configと、私のaddsressバーに行くgeo.wifi.uiをして「の値を変更しhttps://location.services.mozilla.com/v1/geolocate?key=test」。動作します!

uが持っている場合は、位置取得がタイムアウトエラーを、タイムアウト値を大きくしてみてください:

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

1

getCurrentPosition失敗した場合のフォールバック方法として、IPアドレス地理位置情報サービスを使用することをお勧めします。たとえば、API https://ip-api.io

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

1

私たちの場合、それは常に最初に動作しますが、関数を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) => { });
}

0

私は最近この問題に気づきましたが、どのように発生するのかはわかりませんが、Firefoxがキャッシュにロードされたものでスタックすることがあります。キャッシュをクリアしてFirefoxを再起動すると、再び機能するように見えます。



0

皆さんの意見をありがとう、これは私を助けました。

getCurrentPosition()の代わりにwatchPosition()を使用する必要があることに加えて、document.ready()内から先頭に呼び出しを移動する必要があることもわかりました。


0

これは、Firefoxのレスポンシブデザインモードを使用しているときに起こりました。あったバグレポート提出。現時点では、Geolocation APIの使用中はレスポンシブデザインモードを使用しないでください。


0

それは誰かに役立つかもしれません、Androidで私は同じ問題を抱えていましたが、setTimeout 内部を使用し document.ready てそれを見つけました ので、それは私のために機能しましたユーザーが数秒後に彼の場所を許可した場合に備えてタイムアウトを増やす必要があるため、私はそれを60000に保ちましたミリ秒(1分)。ユーザーが1分以内に許可ボタンをクリックした場合に成功関数を呼び出すことができます。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.