- Khả năng & giới hạn
- Luồng cơ bản
- Tuỳ chọn quan trọng
- Demo trực tiếp
- Cấu hình
- Toạ độ hiện tại
- JS Deep-Dive: Geolocation API đúng bài
- 1. Dữ liệu trả về: position & coords
- 2. Chọn getCurrentPosition hay watchPosition?
- 3. Bộ ba tham số vàng
- 4. Promise hóa cho gọn code
- 5. Theo dõi an toàn: quản lý watchId & dọn dẹp
- 6. Xử lý lỗi theo mã chuẩn
- 7. Mẹo UX & hiệu năng
- 8. Permission & fallback
- 9. Chuẩn hoá & bảo vệ dữ liệu
- 10. Pattern gợi ý: lấy nhanh + nâng cấp chính xác
- Thực hành tốt
- Kết luận
Khả năng & giới hạn
- Yêu cầu bảo mật: chỉ hoạt động trên HTTPS (hoặc
http://localhostkhi dev). - Quyền riêng tư: luôn cần người dùng đồng ý, có thể thu hồi bất cứ lúc nào.
- Độ chính xác: tuỳ thiết bị & cảm biến (GPS, Wi-Fi, cell).
enableHighAccuracycho kết quả tốt hơn nhưng tốn pin.
Luồng cơ bản
- Kiểm tra hỗ trợ:
'geolocation' in navigator. - Gọi
getCurrentPositionđể lấy toạ độ 1 lần, hoặcwatchPositionđể theo dõi liên tục. - Truy cập
position.coords(lat, lng, accuracy, speed, heading…) vàposition.timestamp. - Xử lý lỗi qua callback
onError(denied/timeout/unavailable…).
Tuỳ chọn quan trọng
enableHighAccuracy: true để ưu tiên GPS (tốn pin hơn, chậm hơn).timeout: thời gian tối đa (ms) để lấy được vị trí trước khi báo lỗi.maximumAge: chấp nhận vị trí cache (ms) để trả nhanh hơn.
Demo trực tiếp
Cấu hình
Sẵn sàng. (HTTPS + quyền micro-vị trí)
| Permission | — |
| Trạng thái | idle |
| Lỗi gần nhất | — |
Toạ độ hiện tại
| Latitude | — |
| Longitude | — |
| Accuracy | — |
| Altitude | — |
| Speed | — |
| Heading | — |
| Timestamp | — |
Lịch sử cập nhật (watchPosition)
| # | Thời gian | Lat | Lng | ±m |
|---|
JS Deep-Dive: Geolocation API đúng bài
1. Dữ liệu trả về: position & coords
Mỗi lần định vị, trình duyệt trả một đối tượng position gồm:
position.coords.latitude,position.coords.longitude(bắt buộc)position.coords.accuracy(mét, càng nhỏ càng chính xác)position.coords.altitude(m),altitudeAccuracy(m) — có thể nullposition.coords.speed(m/s),heading(độ, 0°=Bắc) — có thể nullposition.timestamp(ms since epoch)
2. Chọn getCurrentPosition hay watchPosition?
- getCurrentPosition: lấy một điểm → hợp cho “tìm cửa hàng gần tôi”, auto điền địa chỉ, set initial map.
- watchPosition: theo dõi liên tục → hợp cho dẫn đường, logger hành trình, geofencing realtime.
3. Bộ ba tham số vàng
enableHighAccuracy: ưu tiên GPS (chính xác cao, tốn pin, chậm hơn). Dùng khi thật cần (dẫn đường, đo quãng đường).timeout: tối đa bao lâu (ms) trước khi báo lỗi. Tránh để 0 (vô hạn) trừ khi bắt buộc.maximumAge: chấp nhận dùng vị trí cache trong N ms để phản hồi tức thì; đặt 0 để buộc đo mới.
| Use case | Gợi ý cấu hình |
|---|---|
| Tìm cửa hàng gần nhất | getCurrentPosition, enableHighAccuracy=false, timeout=5000, maximumAge=60000 |
| Đặt tâm bản đồ lúc mở trang | getCurrentPosition, highAccuracy=false, timeout=3000, maximumAge=300000 |
| Dẫn đường / chạy bộ | watchPosition, highAccuracy=true, timeout=10000, maximumAge=0 |
| Geofencing thông báo | watchPosition, highAccuracy=true, throttling cập nhật 1–3s/lần |
4. Promise hóa cho gọn code
// getCurrentPosition → Promise
function getPosition(opts = {}) {
return new Promise((resolve, reject) => {
if (!('geolocation' in navigator)) return reject(new Error('Geolocation unsupported'));
navigator.geolocation.getCurrentPosition(resolve, reject, opts);
});
}
// Ví dụ dùng:
getPosition({ enableHighAccuracy: false, timeout: 5000, maximumAge: 60000 })
.then(pos => console.log(pos.coords.latitude, pos.coords.longitude))
.catch(err => console.warn('Geo error:', err));
5. Theo dõi an toàn: quản lý watchId & dọn dẹp
let watchId = null;
function startWatch(opts = {}, onUpdate, onError) {
if (!('geolocation' in navigator) || watchId !== null) return;
watchId = navigator.geolocation.watchPosition(onUpdate, onError, opts);
}
function stopWatch() {
if (watchId !== null) {
navigator.geolocation.clearWatch(watchId);
watchId = null;
}
}
6. Xử lý lỗi theo mã chuẩn
function handleGeoError(err) {
switch (err.code) {
case err.PERMISSION_DENIED: // 1
return 'Người dùng từ chối cấp quyền vị trí.';
case err.POSITION_UNAVAILABLE: // 2
return 'Không thể xác định vị trí (GPS/Wi-Fi yếu hoặc dịch vụ lỗi).';
case err.TIMEOUT: // 3
return 'Hết thời gian chờ lấy vị trí.';
default:
return 'Lỗi không xác định.';
}
}
7. Mẹo UX & hiệu năng
- Phản hồi tức thì: cho phép
maximumAge> 0 để hiển thị vị trí gần nhất đã biết, rồi cập nhật khi có đo mới. - Tiết kiệm pin: chỉ bật
enableHighAccuracykhi cần; dừngwatchPositionkhi người dùng rời màn hình (visibilitychange). - Giảm nhiễu: bỏ qua cập nhật nếu
coords.accuracy> ngưỡng (vd 100 m) hoặc nếu chênh lệch < 5–10 m so với lần trước. - Debounce UI: khi nhận nhiều cập nhật nhanh, hãy throttle cập nhật DOM/map (vd mỗi 500–1000 ms).
8. Permission & fallback
// Kiểm tra trạng thái permission (Chrome/Edge/Safari mới)
if ('permissions' in navigator && navigator.permissions.query) {
navigator.permissions.query({ name: 'geolocation' }).then(s => {
console.log('Permission:', s.state); // 'granted' | 'prompt' | 'denied'
});
}
// Fallback mềm: nếu không có geolocation, có thể dùng IP-based geolocation (độ chính xác thấp, chú ý quyền riêng tư).
9. Chuẩn hoá & bảo vệ dữ liệu
- Không lưu lat/lng chính xác nếu không cần; có thể làm coarsening (làm tròn 3–4 chữ số thập phân ~100–10 m).
- Luôn hiển thị trạng thái ghi nhận vị trí, cho phép người dùng tắt theo dõi.
- Chỉ gửi toạ độ lên server sau khi người dùng xác nhận thao tác (ví dụ nút “Dùng vị trí này”).
10. Pattern gợi ý: lấy nhanh + nâng cấp chính xác
// 1) Hiển thị nhanh vị trí cache (nếu có)
getPosition({ enableHighAccuracy: false, timeout: 2000, maximumAge: 300000 })
.then(showOnMap)
.catch(() => {/* im lặng, chuyển bước 2 */})
.finally(() => {
// 2) Nâng cấp độ chính xác (có thể chậm hơn)
getPosition({ enableHighAccuracy: true, timeout: 10000, maximumAge: 0 })
.then(updateOnMap)
.catch(err => showWarning(handleGeoError(err)));
});
TL;DR: Hiểu rõ bộ ba enableHighAccuracy–timeout–maximumAge, chọn đúng giữa getCurrentPosition/watchPosition, quản lý watchId gọn gàng, và xử lý permission/lỗi minh bạch — đó là chìa khóa để Geolocation chạy mượt, tiết kiệm pin và tôn trọng quyền riêng tư.
Thực hành tốt
- Hiển thị trạng thái/permission rõ ràng (prompt/granted/denied) và hướng dẫn cách bật lại.
- Dùng
maximumAgehợp lý để phản hồi nhanh, chỉ bậtenableHighAccuracykhi cần. - Ẩn/giảm độ chính xác của toạ độ khi không cần công khai (privacy by design).
Kết luận
Geolocation API rất dễ dùng: vài dòng JS là có toạ độ realtime. Quan trọng là cân bằng giữa UX, pin/hiệu năng và quyền riêng tư của người dùng.
Bình luận