Computer >> Hướng Dẫn Máy Tính >  >> Lập Trình >> HTML

HTML5 Geolocation không cần SSL (HTTP) - Có thể không?

Không. Kể từ Chrome 50+ (2016), Firefox 55+, Safari, Edge: Geolocation API chỉ hoạt động trên HTTPS (Secure Contexts). Trên HTTP, navigator.geolocation trả về undefined hoặc ném lỗi Permission denied.

Tại sao bắt HTTPS?

  • Bảo mật: Vị trí là dữ liệu nhạy cảm (PII).
  • Ngăn chặn MITM (Man-in-the-middle) theo dõi vị trí user.
  • Chính sách Secure Contexts của W3C: API mạnh (geolocation, camera, mic, payment...) yêu cầu HTTPS.

Giải pháp cho Development (Localhost)

  • localhost, 127.0.0.1, [::1] được coi là Secure Context → Geolocation hoạt động trên HTTP localhost.
  • Dùng lighthouse, ngrok, localhost.run để tunnel HTTPS về local.

Code Geolocation chuẩn (Chỉ chạy trên HTTPS/localhost)

<button id="getLocation">Lấy vị trí</button>
<pre id="output"></pre>

<script>
document.getElementById('getLocation').addEventListener('click', function() {
  var output = document.getElementById('output');
  
  if (!navigator.geolocation) {
    output.textContent = 'Trình duyệt không hỗ trợ Geolocation';
    return;
  }
  
  // Options
  var options = {
    enableHighAccuracy: true,  // Dùng GPS nếu có (chậm hơn, chính xác hơn)
    timeout: 10000,            // Timeout 10 giây
    maximumAge: 0              // Không dùng cache, lấy vị trí mới
  };
  
  navigator.geolocation.getCurrentPosition(success, error, options);
  
  function success(position) {
    var coords = position.coords;
    output.textContent = 
      'Latitude: ' + coords.latitude + '\n' +
      'Longitude: ' + coords.longitude + '\n' +
      'Accuracy: ' + coords.accuracy + 'm\n' +
      'Altitude: ' + (coords.altitude || 'N/A') + 'm\n' +
      'Speed: ' + (coords.speed || 'N/A') + 'm/s\n' +
      'Timestamp: ' + new Date(position.timestamp).toLocaleString();
  }
  
  function error(err) {
    var messages = {
      1: 'PERMISSION_DENIED: Người dùng từ chối chia sẻ vị trí',
      2: 'POSITION_UNAVAILABLE: Không xác định được vị trí',
      3: 'TIMEOUT: Hết thời gian chờ'
    };
    output.textContent = 'Lỗi: ' + (messages[err.code] || err.message);
  }
});
</script>

Watch Position (Theo dõi liên tục)

var watchId = navigator.geolocation.watchPosition(success, error, options);

// Dừng theo dõi
navigator.geolocation.clearWatch(watchId);

Fallback cho HTTP (Không khuyến khích production)

Nếu bắt buộc chạy trên HTTP (legacy intranet), dùng IP-based geolocation qua API bên thứ 3:

// Ví dụ dùng ipapi.co (free tier)
fetch('https://ipapi.co/json/')
  .then(r => r.json())
  .then(data => {
    console.log('IP-based location:', data.city, data.country_name, data.latitude, data.longitude);
  });

⚠️ Độ chính xác thấp (cấp độ thành phố/ISP), không phải vị trí thực của user.

Tóm tắt

Môi trườngGeolocation API
HTTPS Production✅ Hoạt động
HTTP Production❌ Chặn (Permission denied)
localhost / 127.0.0.1✅ Hoạt động (Secure Context)
file:// protocol❌ Chặn
IP-based API (fallback)✅ HTTP/HTTPS đều được, nhưng kém chính xác