Geolocation API: Lấy vị trí người dùng chỉ với vài dòng JS

Geolocation API cho phép trình duyệt cung cấp vị trí hiện tại của người dùng (vĩ độ/kinh độ) sau khi họ cấp quyền. Bạn có thể xây tính năng “tìm cửa hàng gần nhất”, tự động điền địa chỉ, log hành trình, hay cảnh báo theo khu vực — tất cả ngay trên web.

Geolocation API: Lấy vị trí người dùng chỉ với vài dòng JS

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://localhost khi 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). enableHighAccuracy cho kết quả tốt hơn nhưng tốn pin.

Luồng cơ bản

  1. Kiểm tra hỗ trợ: 'geolocation' in navigator.
  2. Gọi getCurrentPosition để lấy toạ độ 1 lần, hoặc watchPosition để theo dõi liên tục.
  3. Truy cập position.coords (lat, lng, accuracy, speed, heading…) và position.timestamp.
  4. 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

8000ms (0 = vô hạn)

0ms (chấp nhận vị trí cache)

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
Mở trên Maps

Gợi ý: mở Google Maps với?q=lat,lnghoặc OpenStreetMap với#map=zoom/lat/lng.

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ể null
  • position.coords.speed (m/s), heading (độ, 0°=Bắc) — có thể null
  • position.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 enableHighAccuracy khi cần; dừng watchPosition khi 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 enableHighAccuracytimeoutmaximumAge, 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 maximumAge hợp lý để phản hồi nhanh, chỉ bật enableHighAccuracy khi 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


  • Không có bình luận.

Init Toolbox

Nhấn Ctrl + \ trên máy tính, hoặc vuốt sang trái ở bất kỳ đâu trên mobile.

Đăng nhập





Đang tải...