# 地图定位失败问题解决方案

## 问题原因

部署到服务器后地图定位失败的主要原因：

### 1. **HTTPS 要求（最关键）**
- 浏览器的 Geolocation API 要求必须在**安全上下文**（Secure Context）下才能工作
- 安全上下文包括：
  - `https://` 协议
  - `localhost` 或 `127.0.0.1`（开发环境）
  - `file://` 协议（本地文件）
- 如果服务器使用 HTTP 协议，浏览器会直接拒绝定位请求，返回 `PERMISSION_DENIED` 错误

### 2. 时序问题
- 原代码在地图创建后立即调用定位，但高德定位插件可能还未加载完成
- 导致 `this.geolocation` 为 `null`，定位失败

### 3. 缓存配置不当
- 原代码设置了 5 分钟缓存（`maximumAge: 300000`），可能导致使用过期位置

## 解决方案

### 方案一：启用 HTTPS（推荐）

这是最彻底的解决方案，也是生产环境的标准做法。

#### 1. 申请 SSL 证书
- 免费证书：Let's Encrypt、阿里云免费证书、腾讯云免费证书
- 付费证书：各大云服务商提供

#### 2. Nginx 配置示例
```nginx
server {
    listen 80;
    server_name yourdomain.com;
    # 重定向到 HTTPS
    return 301 https://$server_name$request_uri;
}

server {
    listen 443 ssl http2;
    server_name yourdomain.com;
    
    ssl_certificate /path/to/cert.pem;
    ssl_certificate_key /path/to/key.pem;
    
    location / {
        root /path/to/your/dist;
        try_files $uri $uri/ /index.html;
    }
}
```

### 方案二：使用 IP 定位（降级方案）

如果暂时无法启用 HTTPS，可以使用高德的 IP 定位功能（精度较低，约 1-5 公里）。

修改高德定位配置：
```javascript
this.geolocation = new AMap.Geolocation({
  enableHighAccuracy: false,  // 关闭高精度定位
  timeout: 10000,
  maximumAge: 0,
  convert: true,
  showButton: false,
  showMarker: false,
  showCircle: false,
  panToLocation: false,
  zoomToAccuracy: false,
  noIpLocate: 0,  // 允许使用 IP 定位
  GeoLocationFirst: false  // 优先使用 IP 定位
})
```

### 方案三：使用设备实时位置（已实现）

你的代码中已经实现了设备实时位置轮询（`setupRealtimePolling`），可以作为主要定位方式：
- 优先使用设备上报的实时位置
- 浏览器定位作为辅助手段

## 代码改进说明

已对你的代码做了以下优化：

### 1. 修复时序问题
- 在高德定位插件加载完成后才调用定位
- 增加了 `tryAutoLocation()` 方法，确保插件就绪后再定位

### 2. 增强错误处理
- 详细的错误日志输出
- 区分不同的定位失败原因
- HTTPS 环境检测和提示

### 3. 优化配置
- 移除缓存（`maximumAge: 0`），确保获取最新位置
- 增加重试次数（3次 → 5次）
- 添加详细的控制台日志

### 4. 用户体验优化
- 自动定位失败时不显示错误提示（避免干扰）
- 手动定位失败时显示详细错误信息
- 检测 HTTPS 环境并给出提示

## 测试步骤

### 1. 本地测试（HTTP）
```bash
# 启动开发服务器
npm run dev:h5
```
- 访问 `http://localhost:xxxx`
- 应该能正常定位（localhost 是安全上下文）

### 2. 服务器测试（HTTP）
- 部署到服务器
- 访问 `http://your-server-ip`
- 会提示定位失败（非安全上下文）
- 可以使用 IP 定位或设备实时位置

### 3. 服务器测试（HTTPS）
- 配置 SSL 证书
- 访问 `https://your-domain.com`
- 应该能正常定位

## 调试方法

### 1. 查看控制台日志
打开浏览器开发者工具（F12），查看 Console 标签：
```
[job-create] 创建地图使用默认中心点: [113.382, 22.5211]
[job-create] 高德定位插件加载完成
[job-create] 开始自动定位...
[job-create] 开始调用高德定位 getCurrentPosition...
[job-create] 定位回调 status: error result: {...}
```

### 2. 检查 HTTPS 状态
在控制台输入：
```javascript
console.log('isSecureContext:', window.isSecureContext)
console.log('protocol:', window.location.protocol)
```

### 3. 测试高德定位
在控制台输入：
```javascript
navigator.geolocation.getCurrentPosition(
  pos => console.log('成功:', pos),
  err => console.log('失败:', err)
)
```

## 推荐方案

根据你的实际情况选择：

1. **生产环境**：必须使用 HTTPS + 高精度定位
2. **测试环境**：可以使用 HTTP + IP 定位 + 设备实时位置
3. **内网环境**：可以使用 IP 地址访问（如 `http://192.168.x.x`），但定位精度低

## 参考资料

- [MDN - Geolocation API](https://developer.mozilla.org/zh-CN/docs/Web/API/Geolocation_API)
- [高德地图 JS API - 定位](https://lbs.amap.com/api/javascript-api/guide/services/geolocation)
- [浏览器安全上下文](https://developer.mozilla.org/zh-CN/docs/Web/Security/Secure_Contexts)
