由于与 ionic://localhost 的不安全连接(在 cordova-ios 上),对地理位置的访问被阻止
Posted
技术标签:
【中文标题】由于与 ionic://localhost 的不安全连接(在 cordova-ios 上),对地理位置的访问被阻止【英文标题】:Access to geolocation was blocked over insecure connection to ionic://localhost (on cordova-ios) 【发布时间】:2020-08-22 09:41:21 【问题描述】:我正在尝试使用我创建的“location.service”获取移动设备的位置和方向(指南针方向)。它曾经在android和ios上都可以工作,现在在ios上,我得到了位置,但是设备方向出错。
[被阻止] 对地理位置的访问因连接不安全而被阻止 到 ionic://localhost。
Geolocation PositionError code: 1, message: "Origin 没有 使用地理定位服务的权限”
我已经在 *.plist 文件上尝试了所有这些:
我正在使用:
@angular/cli 7.3.9cordova-lib@9.0.1
平台: 安卓8.1.0 ios 5.1.1 插件(缩短): cordova-plugin-ionic-webview 4.1.1 “cordova-plugin-ionic-webview” cordova-plugin-geolocation 4.0.2“地理位置”当我cordova build ios
时,在我的 iPhone (ios 13.4.1) 上从 Xcode 运行它并检查 Safari 的开发控制台:
位置服务:
import Injectable from '@angular/core';
import BehaviorSubject, combineLatest, fromEvent, Observable, of, timer from 'rxjs';
import HttpClient from '@angular/common/http';
import map, switchMap from 'rxjs/operators';
import Globals from '../globals';
export interface DefiLocation
accuracy: number;
altitude: number;
altitudeAccuracy: number;
heading: number;
latitude: number;
longitude: number;
speed: number;
compass: number;
@Injectable(
providedIn: 'root'
)
export class LocationService
errorMessage$: string;
currentLocation$: BehaviorSubject<
accuracy?: number,
altitude: number,
altitudeAccuracy: number,
heading: number,
latitude: number,
longitude: number,
speed: number
> = new BehaviorSubject(
accuracy: 0,
altitude: 0,
altitudeAccuracy: 0,
heading: 0,
latitude: 32.5,
longitude: 35,
speed: 0,
);
currentCompass$: BehaviorSubject<number> = new BehaviorSubject(0);
currentCompass: number = 0;
currentPosition:
accuracy: 0,
altitude: 0,
altitudeAccuracy: 0,
heading: 0,
latitude: 32.5,
longitude: 35,
speed: 0,
;
locationTimer;
sendLocationError: boolean = true;
constructor(public globals: Globals)
this.isCurrentPosition$.next(true);
this.trackMe();
private trackMe()
if (this.globals.iphone)
window.addEventListener('deviceorientation', (event) =>
this.currentCompass$.next(Math.round(event['webkitCompassHeading']));
);
//
else
window.addEventListener('deviceorientationabsolute', (event) =>
this.currentCompass$.next(360 - Math.round(event['alpha']));
, true);
if (navigator.geolocation)
this.locationTimer = timer(0, 100).subscribe(tick =>
navigator.geolocation.getCurrentPosition((position) =>
this.currentLocation$.next(position.coords);
this.isCurrentPosition$.next(true);
this.sendLocationError = true;
, (err) =>
this.isCurrentPosition$.next(false);
this.sendError(err.message);
console.log(err);
this.errorMessage$ = err.message;
console.log(this.errorMessage$);
,
enableHighAccuracy: true
);
);
else
alert('Geolocation is not supported by this browser.');
this.sendError('navigator.geolocation = null ("Geolocation is not supported by this browser.")');
getCurrentLocation$(): Observable<DefiLocation>
return combineLatest(this.currentCompass$.asObservable(), this.currentLocation$.asObservable())
.pipe(
map(([compass, location]) =>
return
longitude: location.longitude,
latitude: location.latitude,
accuracy: location.accuracy,
altitude: location.altitude,
altitudeAccuracy: location.altitudeAccuracy,
heading: location.heading,
speed: location.speed,
compass
;
));
sendError(error)
if (this.sendLocationError)
this.sendLocationError = false;
window['cordova'].plugins.firebase.analytics.logEvent('user_location_failed', param1: error);
setTimeout(function() this.sendLocationError = true; , 5000);
【问题讨论】:
你有什么运气吗?我使用的是普通的 Cordova(无 Ionic),尝试“升级”到 wkwebview 时遇到类似错误“由于与 app://localhost 的不安全连接而阻止了对地理位置的访问”。 我写了我得到的所有东西...@JessePangburn 谢谢!我的问题是在使用 WKWebView 之前我不需要 cordova-plugin-geolocation 插件。添加这个插件解决了这个问题,尽管人们应该知道该插件有一个硬编码的 5 米距离过滤器,这与没有插件时 navigator.geolocation.watchPosition 的工作方式不同。 【参考方案1】:原来错误消息与设备的位置无关(当我修复位置时,错误仍然存在)。方向有点问题,但我有一个答案:
-
位置 - 当我请求 .plist 文件中的所有正确权限时,我收到了正确的位置。 Here is a nice explanation 关于权限。顺便说一句,我正在使用cordova-plugin-geolocation。
方向(指南针)-根据“Safari 13 Release Notes”:
在 iOS 上为 DeviceMotionEvent 和 设备方向事件。
一个。 Permission API - 到目前为止,Chrome 和 Safari 只显示“在没有用户手势的情况下询问设备方向”的警告,但在 ios 13+ 上,苹果又迈出了一步,完全阻止了它。 The full w3c discussion。 在下面的最后代码示例中询问权限的正确方法示例。
b.旧的/新的替代方案 (cordova-plugin-device-orientation) - 因为这种行为在应用程序中确实不自然,所以我尝试了一个使用原生资源的旧的已弃用插件,它有效,幸运的是,现在该插件实际上已被弃用!
我的完整代码与后备
-
尝试从 deviceready 上的浏览器请求位置和方向的许可(适用于 android 和 ios)。
如果没有,请尝试orientation-plugin(原生资源)。
如果没有,则请求用户手势权限作为 ios13+ 网络协议状态。
此运行已在设备上准备就绪:
private trackMe()
// compass listener (also ios13+ fallback at "compassPremissioniOS13" funtion)
if (typeof DeviceOrientationEvent['requestPermission'] !== 'function')
const deviceOrientationLestener = (event) =>
if (this.globals.iphone)
this.currentCompass$.next(event['webkitCompassHeading']);
else
if (event.absolute)
this.currentCompass$.next(360 - event.alpha);
else
window.removeEventListener('deviceorientation', deviceOrientationLestener);
window.addEventListener('deviceorientationabsolute', (eventB) =>
this.currentCompass$.next(360 - eventB['alpha']);
, true);
;
window.addEventListener('deviceorientation', deviceOrientationLestener);
else
document.addEventListener('deviceready', () =>
navigator['compass'].watchHeading((head) =>
this.currentCompass$.next(head.trueHeading);
, (error) => console.log(error), frequency: 10);
, false);
// GET LOCATION - energy saving and preformance inhancing for mobile, dumm and cyclic for desktop.
if (this.globals.cordova)
document.addEventListener('deviceready', () =>
if (navigator.geolocation)
navigator.geolocation.watchPosition((position) =>
this.currentLocation$.next(position.coords);
this.isCurrentPosition$.next(true);
this.sendLocationError = true;
, (err) =>
this.isCurrentPosition$.next(false);
this.sendError(err.message);
this.errorMessage$ = err.message;
,
enableHighAccuracy: true
);
else
alert('Geolocation is not supported by this browser.');
this.sendError('navigator.geolocation = null ("Geolocation is not supported by this browser.")');
, false);
else
if (navigator.geolocation) // fallback for desktop testing
this.locationTimer = timer(0, 100).subscribe(tick =>
navigator.geolocation.getCurrentPosition((position) =>
this.currentLocation$.next(position.coords);
this.isCurrentPosition$.next(true);
this.sendLocationError = true;
, (err) =>
this.isCurrentPosition$.next(false);
this.sendError(err.message);
this.errorMessage$ = err.message;
,
enableHighAccuracy: true
);
);
else
alert('Geolocation is not supported by this browser.');
this.sendError('navigator.geolocation = null ("Geolocation is not supported by this browser.")');
当用户按下导航按钮时运行:
compassPremissioniOS13$()
return new Promise((resolve, reject) =>
if (navigator.geolocation)
if (typeof DeviceOrientationEvent['requestPermission'] === 'function')
DeviceOrientationEvent['requestPermission']()
.then(permissionState =>
if (permissionState === 'granted')
window.addEventListener('deviceorientation', (event) =>
this.currentCompass$.next(event['webkitCompassHeading']);
);
resolve('User accepted');
else
reject('User declined');
)
.catch(console.error);
else
alert('deviceorientation is not supported by this browser.');
this.sendError('deviceorientation = null ("deviceorientation is not supported by this browser.")');
);
【讨论】:
以上是关于由于与 ionic://localhost 的不安全连接(在 cordova-ios 上),对地理位置的访问被阻止的主要内容,如果未能解决你的问题,请参考以下文章