Ask questions
Since we are in a business that relies heavily on LBS, during the two years of the business iteration we encountered numerous problems with obtaining user location on Web pages:
- Why can’t I get user location information on H5 when I have opened app location authorization?
- Why do I still get the user’s location information on H5 when I turn off the app’s location authorization?
- Why did I pop up the H5 location authorization popup when I entered the page? Can the text on the popup be changed?
- I have rejected the H5 location authorization popover, how do I re-pop the authorization popover?
Years of experience in the pit, summarized into the following article, the following to answer these questions.
Classification of positioning modes on the Web
The positioning methods on the Web can be classified into the following three types:
- H5 native: navigator.geolocation
- IP location: Using IP to obtain location through the CGI interface
- App location: The APP obtains the location and passes it to the front end
Based on these three categories, we can use the following ways to position.
-
navigator.geolocation
The native location of H5 is navigator. Geolocation.
-
Tencent map front-end positioning components
Tencent map front-end positioning component does some encapsulation based on navigator. Geolocation. If the original positioning fails, it will downgrade to IP to obtain positioning, and at the same time, some cache optimization has been made for the location information obtained.
-
Tencent map IP location API
Through the CGI interface request to get a relatively low precision location information.
-
WeChat JSSDK
Wechat provides JSSDK, H5 can be directly called to obtain location information. In essence, location information is obtained by passing app through JsBridge. Similarly, we can also pass the location information obtained by the app through url parameters and other ways.
The following is a detailed description of the various location methods called. For ease of use, the various location methods are implementations of the following LocationInterface interface:
// Latitude and longitude, etc
export interface LocationData {
lat: number.lng: number.type? :string,}// Locate flag, which indicates the type of the returned result
export enum LocationFlag {
LocationSuccss = 1.// Use GPS to pinpoint the location
LocationIpSuccss = 2.// Locate the IP address
LocationFailed = 3.// Failed to locate
}
// The location result returned
export type LocationResult = {
location: LocationData
flag: LocationFlag
};
// Interfaces to be implemented in different positioning scenarios
export interfaceLocationInterface { getLocation(options? : LocationOptions):Promise<LocationResult>;
}
Copy the code
1. navigator.geolocation
The document
Developer.mozilla.org/zh-CN/docs/…
use
// H5 native location localization
export default class TencentMapApiLocation implements LocationInterface {
getLocation(): Promise<LocationResult> {
return new Promise((resolve, reject) = > {
function geoShowPosition(position) {
if (position) {
const location = { lat: position.coords.latitude, lng: position.coords.longitude };
resolve({ location, flag: LocationFlag.LocationSuccss });
} else{ reject(); }}function geoShowError(error) {
console.log(`getPosError:${error.code}.${navigator.geolocation}.${error.message}`); reject(); } navigator.geolocation.getCurrentPosition(geoShowPosition, geoShowError); }); }}Copy the code
The advantages and disadvantages
Advantages:
- Independent of external interfaces and components, accurate location information.
- Whether location information can be obtained is strongly related to whether location authorization is enabled in the APP embedded with H5. The situation that location authorization can still be obtained will not be turned off.
Disadvantages:
- After the user rejects the authorization popup of H5, the user needs to reset the system permission to obtain the positioning authorization (restarting the authorization setting of app is also useless).
- The location authorization popup window of H5 is popup by the browser, and the document cannot be customized. There is no way to explain to the user what location information is used for in this popup window.
Applicable scenario
Navigator. geolocation is applicable to most scenarios for obtaining positioning, and whether it can obtain positioning is completely related to whether users enable location authorization for app. There is no need to worry about problems in app compliance check.
Answer the questions above
Question 1. Why can’t I get user location information on H5 when I have opened app location authorization?
This is because H5 calls navigator.geolocation to obtain location, which requires app authorization as well as “browser authorization”.
Question 3. Why did THE location authorization popup of H5 pop up when I entered the page? Can the text on the popup be changed?
Can’t.
Q4. I rejected the location authorization popup of H5. How can I pop up the location authorization popup again?
If the authorization popup of the mobile browser is rejected by the user, you need to reset the system location Settings to pop up the popup again.
On iOS, the path to reset location permissions is System – General – Restore – Restore Location and Privacy.
2. Tencent map front-end positioning component
The document
Lbs.qq.com/webApi/comp…
use
// Use the SDK to get the location
export default class TencentMapLocation implements LocationInterface {
public getLocation(options: LocationOptions): Promise<LocationResult> {
return new Promise((resolve, reject) = > {
function geoShowPosition(location) {
resolve({ location, flag: LocationFlag.LocationSuccss });
}
function geoShowError() {
reject();
}
loader('https://3gimg.qq.com/lightmap/components/geolocation/geolocation.min.js'.() = > {
// eslint-disable-next-line no-undef
const geolocation = new (window as any).qq.maps.Geolocation(
tencentMapConfig.GEO_KEY,
tencentMapConfig.GEO_REFERER,
);
const tencentMapOptions = {
timeout: options.timeout, }; geolocation.getLocation(geoShowPosition, geoShowError, tencentMapOptions); }); }); }}Copy the code
The advantages and disadvantages
advantages
- The front-end positioning component of Tencent Map is optimized on the basis of the native H5 positioning, including the cache of the obtained location information. When the native H5 positioning fails (the user does not authorize the app permission or refuses the authorization popup), the IP positioning will be degraded.
- Compared with the original, the success rate of obtaining information will be improved to some extent.
disadvantages
- Whether users can obtain location information is not strongly related to whether the app’s location authorization is enabled. Users who disable app location authorization can still obtain location information through cache and IP location.
- Because H5 native positioning is preferred, the positioning authorization window of H5 will still pop up.
Applicable scenario
It is suitable for businesses with high dependence on LBS. It is the preferred positioning method among several positioning methods.
As the acquisition of location information is not strongly related to whether the user authorizes the APP, there may be risks in compliance inspection.
Answer the questions above
Question 2. Why do I still get the user’s location information on H5 when I turn off the app’s location authorization?
Due to the optimization of Tencent map front-end positioning components, users can still obtain location information through IP positioning and cache when they close app positioning authorization.
Since our business is embedded in multiple apps, we often need to modify the page with app to pass the compliance inspection recently. The commonly used modification scheme is to use navigator. Geolocation to obtain location information, or directly use the location information obtained by APP.
3. Positioning of wechat SDK
The document
Developers.weixin.qq.com/doc/offiacc…
use
// Use wechat SDK to obtain user location information
export default class WechatSdkLocation implements LocationInterface {
public getLocation(): Promise<LocationResult> {
return new Promise((resolve, reject) = > {
configWx(['getLocation'.'openLocation'], []).then((wx) = > {
const tmp = {
type: 'gcj02'.success(res) {
const location = {
lat: parseFloat(res.latitude),
lng: parseFloat(res.longitude),
};
resolve({ location, flag: LocationFlag.LocationSuccss });
},
fail(error) {
console.log('WechatSdkLocation', error); reject(); }}; wx.getLocation(tmp); }) .catch((error) = > {
console.log('WechatSdkLocation', error); reject(); }); }); }}Copy the code
The advantages and disadvantages
advantages
- High speed, high accuracy, high success rate
- There will be no location authorization pop-ups.
- Whether the location information can be obtained depends entirely on whether the APP is authorized.
disadvantages
- No, just use this in wechat WebView.
Applicable scenario
Only wechat WebView.
Before using it, you need to inject the configuration information of wechat JS-SDK.
Use it in other apps
The essence of this positioning method is to directly use the positioning ability of the APP. Similarly, in other apps, we can also acquire location information in a similar way. All you need to do is pass messages between app and H5, via URL parameters, jsBridge, etc., in many ways.
4. IP positioning of Tencent Map API
The document
Lbs.qq.com/service/web…
use
// Use Tencent Map API to get user location information through IP
export default class TencentMapApiLocation implements LocationInterface {
public getLocation(): Promise<LocationResult> {
return new Promise((resolve, reject) = > {
axios.get(`https://apis.map.qq.com/ws/location/v1/ip?key=${tencentMapConfig.GEO_KEY}`).then((res) = > {
constresult = (res? .data? .result) || {};constlocation = (result? .location) || {};if (location) {
resolve({ location, flag: LocationFlag.LocationIpSuccss });
} else {
reject();
}
})
.catch((error) = > {
console.log('TencentMapApiLocation', error); reject(); }); }); }}Copy the code
The advantages and disadvantages
advantages
- High success rate
- No H5 authorization popup required, no APP authorization required
disadvantages
- Accuracy is low, generally only the latitude and longitude of the city
- The number of API requests is limited. Enterprise users can apply for a quota of 300w times per day.
Applicable scenario
IP location is generally used on the server and can be used as a degraded solution of other location methods. If the front end fails to obtain user location information, the server uses IP location to pull LBS service data.
Because of quotas, the server can cache the location information of a single IP address to reduce the use of quotas.
Encapsulate the
We certainly don’t want to think that much about business development. I need the location information, call the component interface, get the location information, and that’s it.
So let’s encapsulate all of these schemes, and just expose a getLocation interface.
/ * * *@module Location Location *@description Positioning tools, support native H5 positioning, Tencent map positioning, wechat SDK positioning, IP positioning */
class Location {
public static locationFlag = LocationFlag;
private static instance: Location = new Location();
private static env;
public static getInstance() {
return this.instance;
}
/** * Obtain location information *@exports getLocation
* @param {object} Options Location parameters *@param {number} Options. timeout Location timeout period *@param {boolean} Options. useWxSdk In the wechat environment, whether to preferentially use the wechat Sdk to locate *@param {boolean} Options. useTencentMapApi whether to useTencentMapApi for IP location *@param {boolean} Options. useH5Geolocation Whether to use the native IP address *@param {boolean} Options. cache Indicates whether to cache. */ is recommended
public static getLocation(options: LocationOptions) {
// Populate the default data
// ...
return new Promise((resolve, reject) = > {
// Use sessionStorage to store location information
/ /... Some logic for handling caching
// Instantiate positioning components for different scenarios
if (options.useWxSdk && Location.env.isWeixin) {
this.getInstance().locationHandle = new WechatSdkLocation();
} else if (options.useTencentMapApi) {
this.getInstance().locationHandle = new TencentMapApiLocation();
} else if (options.useH5Geolocation) {
this.getInstance().locationHandle = new H5GeolocationLocation();
}
this.getInstance().locationHandle.getLocation(options).then((res) = > {
resolve(res);
// Cache location information
/ /... Save location information
})
.catch((error) = > {
reject(error);
});
});
}
private locationHandle: LocationInterface;
constructor() {
Location.env = initEnv();
this.locationHandle = newTencentMapLocation(); }}Copy the code