web-dev-qa-db-ja.com

ユーザーがfirefoxで位置情報の共有を拒否した場合、関数failは呼び出されません

だから私はこのjavascriptコードを持っています。 safariとchromeでは、ユーザーが場所の共有を拒否すると、本来の機能に失敗します。ただし、Firefoxではそうではありません。

感謝します。

function initGeolocation()
{
    if( navigator.geolocation )
    {          
          // Call getCurrentPosition with success and failure callbacks
          navigator.geolocation.getCurrentPosition( success, fail );
    }
    else
    {
          alert("Sorry, your browser does not support geolocation services.");
    }
}

 var map;
 function success(position)
 {

     var longIDText = document.getElementById('longID');
     var latIDText = document.getElementById('latID');
     longIDText.value = position.coords.longitude;
     latIDText.value = position.coords.latitude;
     document.getElementById('coordSubmitID').click();
  }

  function fail(error)
  {
          alert("FAAAAAAAAAAIIIIIIIIIL")
          var Zip_code ;
          while (true){
              // Could not obtain location

              Zip_code = Prompt("Please enter your current address or Zip code","");


              if ( Zip_code == "" ) {
                  alert(Zip_code +" is not a valid address. Please try again.");
              } 
              else{
                break;
              }
          }
          var zipIDText = document.getElementById('zipID');
          zipIDText.value = Zip_code;
          document.getElementById('coordSubmitID').click();
  }
47
theRealWorld

Firefoxの場合 そのようですPERMISSION_DENIEDは、「共有しない」が選択されている場合にのみ発生しますonly。ダイアログが閉じられるか、「今はしない」が選択された場合、事実上何も起こりません- mozillas geolocation demo でも、許可UIを閉じても何も起こりません。

これは、ユーザーが確認UIを閉じたため、または非同期要求を正常に開始したため、getCurrentPositionが返される可能性があることを意味します-両者を区別する方法はないようです。

https://bugzilla.mozilla.org/show_bug.cgi?id=6755

29
Alex K.

これは本当の苦痛であり、明らかに望ましくない機能です。

私が今まで待っているユーザーを保存するために使用している回避策は、タイムアウトを設定して待機スピナーが3秒後に表示されているかどうかを確認し、そうであればそれを非表示にして手動の郵便番号入力を表示することです:

var latlng;

var waitTime = 3000;
try {
    if (navigator.geolocation) {
        navigator.geolocation.getCurrentPosition(function (position) {
            success(position);
        }, showError);
    } else {
        showError("NOT-SUPPORTED");
    }
    var t = setTimeout(function () {
        if ($("#getZip div.loading").css("display") != "none") {
            $("#getZip div.loading").hide();
            $("#errorZip").show();
        }
    }, waitTime);
} catch (evt) {
    alert(evt);
}
21
Jamie

Alexleonardが指摘したように、このために見つけた唯一の信頼できるクロスブラウザソリューションは、setTimeout()latLngオプションとして、timeoutオブジェクト/変数の状態をチェックするgetCurrentPosition()を持つことです。 ]が確実に機能しないようです。以下の例は、IE11、Chrome33、Firefox28でテストされました。

JQuery promiseを使用するより完全なソリューションについては、ここで私の要点を確認してください。 https://Gist.github.com/GFoley83/10092929

例-F12キーを押し、コンソールに貼り付けて実行します

var latLng,
    geoOptions = {
        enableHighAccuracy: false,
        timeout: 5000, // Wait 5 seconds
        maximumAge: 300000 //  Valid for 5 minutes
    };

var userLocationFound = function(position){
    latLng = {
        lat: position.coords.latitude,
        lng: position.coords.longitude
    };
    window.console.log("User confirmed! Location found: " + latLng.lat + ", " + latLng .lng);
}

var userLocationNotFound = function(){
    latLng = {
        lat: -41.29247, // fallback lat 
        lng: 174.7732  // fallback lng
    };
    window.console.log("Fallback set: ", latLng);
}

window.navigator.geolocation.getCurrentPosition(userLocationFound, userLocationNotFound, geoOptions);

setTimeout(function () {
    if(!latLng){
        window.console.log("No confirmation from user, using fallback");
        userLocationNotFound();
    }else{
        window.console.log("Location was set");
    }
}, geoOptions.timeout + 1000); // Wait extra second
13
GFoley83

これは実際にはChromeでも問題であることに注意してください。

Chrome「サイトはあなたの場所を知りたい」という通知が表示されます-オプションとして「許可」と「拒否」を提供します。UIデザインでは、ユーザーはどちらかを選択する可能性が高くなります。 AllowまたはDenyは、navigator.geolocation.getCurrentPosition関数への回答を返しますが、ユーザーはアドバイザリ通知の右端にある「X」をクリックすることもできます。これは、「Not now」をクリックすることと本質的に同じです。 Firefoxで。

結果は関数に返されません。

この結果を可能にするために、タイマーを実装する必要があるようです。

4
alexleonard

これは設計どおりであり、明らかに問題ではありません。 https://bugzilla.mozilla.org/show_bug.cgi?id=6755 を参照してください

この機能を使用する開発者は、Firefoxのブラウザー固有の回避策を考え出す必要があります。

注目すべきは、エンドユーザーによる実際の位置情報の使用に関するFF開発者のコ​​メントに基づいて、明らかにFirefox開発者はエンドユーザーが製品で行っていることに関する詳細なデータを収集していることです。

4
Chris

約束を使用します。私たちが抱えている同じ問題を解決するために、独自のバージョンの$ qを備えたangularjsを使用しています。

            $scope.ByUserPosition = function () {
                //http://www.w3.org/TR/geolocation-API/
                var deferred = $q.defer();

                deferred.promise.then(findByPosition, function (data) {
                    console.log('error', data);
                });

                var resolveBy = 1000 * 30;
                navigator.geolocation.getCurrentPosition(function (position) {
                    deferred.resolve({ latitude: position.coords.latitude, longitude: position.coords.longitude });
                }, function (err) {
                    deferred.reject(err);
                }, {
                    enableHighAccuracy: true,
                    timeout: resolveBy,
                    maximumAge: 0
                });

                $timeout(function() {
                    deferred.reject('timed out');
                }, resolveBy)
            };
3
Leblanc Meneses

この問題の唯一の解決策は次のとおりです。

  1. ユーザーがボタンをクリックして現在地を自動的に取得したら、スピナーとその横にあるリンクを表示します(例:キャンセル)。
  2. 彼が位置情報の共有を有効にした場合、問題はありません。 Firefoxのポップアップを閉じることを決定した場合、スピナーは表示されますが、「キャンセル」リンクをクリックしてスピナーを停止し、ポップアップを閉じるためのインジケーターを表示できます。

これが役立つことを願っています:)

1
AMustafa

編集(ダウン投票後)6-11-201

この回答の下で述べたように、これはユーザーが場所へのアクセスを拒否した場合の問題を解決しません。 downvoteに正しいです。タイムアウトはとにかく使用するべきものであるため、ここで答えを保持します。どの答えにも表示されません。

関数navigator.geolocation.getCurrentPosition()には、タイムアウトを送信するオプションがあります。

navigator.geolocation.getCurrentPosition(
     function (position){
        //do someting with position
     },
     function (error){
        // do something with the error (like the code)
     }, 
     {timeout:10000}
);

キャッシュされた位置の年齢(maximumAge)などのその他のオプション。タイムアウトと最大時間はミリ秒単位であるため、10000 = 10秒です。

ところで、デフォルトのタイムアウトは無限です...ですので、タイムアウトを設定しないと、エラーのためにコールバックを呼び出すことはありません。

ジェイミーが答えたようなオプションで、私は言うでしょう:

if (navigator.geolocation) {
        navigator.geolocation.getCurrentPosition(function (position) {
            success(position);
        }, showError, {timeout:3000});
    }
1
michel.iamit

Vanilla es6 Promisesを使用して、私の問題を解決します。 @LeblancMenesesの回答に触発されました。

if(navigator.geolocation) {
  let promise = new Promise((resolve, reject) => {
    navigator.geolocation.getCurrentPosition(
      (position) => {
        resolve(position)
      },
      (error) => {
        resolve(error)
      }
    )
    window.setTimeout(() => {
      resolve({})
    }, 8000)
  })
  promise.then((result) => {
      // do something with result
  })
} else {
  console.log('no geolocation available')
}
0
Harry Moreno