
在使用 `fetch()` 调用 django api 时,若在 `.then(response => response.json())` 后误调用 `json.stringify()`,会导致原本已解析的 javascript 对象被重新转为字符串,从而丢失对象属性(如 `features`),引发 `undefined` 错误。
问题根源在于对 response.json() 返回值的理解偏差。response.json() 是一个 异步解析方法,它返回一个 Promise,该 Promise 解析后得到的是一个原生 JavaScript 对象(例如 GeoJSON 格式的对象),而非字符串。而后续链式调用的 JSON.stringify(response) 会将这个对象再次序列化为 JSON 字符串——这不仅多余,更直接破坏了数据结构的可访问性。
以下是修复后的正确代码:
fetch('/guidebook/api/peak-data/')
.then(response => {
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
return response.json(); // ✅ 正确:返回 Promise
})
.then(data => {
console.log('Parsed GeoJSON object:', data);
console.log('Type of data:', typeof data); // → "object"
console.log('Features count:', Array.isArray(data.features) ? data.features.length : 0);
// ✅ 现在可以安全访问 features、properties、geometry 等字段
if (data.features && data.features.length > 0) {
const firstFeature = data.features[0];
console.log('First peak coordinates:', firstFeature.geometry?.coordinates);
console.log('First peak name:', firstFeature.properties?.peak_name);
}
})
.catch(error => {
console.error('Fetch or parsing failed:', error);
}); ⚠️ 关键注意事项:
- 不要重复序列化:response.json() 已完成解析,无需也不应再调用 JSON.stringify();否则 data 将是字符串,data.features 必然为 undefined。
- Django 端需确保返回合法 GeoJSON:你当前使用 serialize('geojson', ...) 是正确的,但需确认 Peak 模型中 peak_coordinates 字段能被 django.contrib.gis 正确序列化(建议显式指定 srid=4326 并验证数据库中坐标不为空)。
- 添加 HTTP 状态检查:response.ok 可提前捕获 4xx/5xx 错误,避免 response.json() 在非 2xx 响应下抛出异常。
- JsonResponse(safe=False) 的适用性:由于 serialize(...) 返回的是字符串(非字典),你必须设 safe=False,这是合理的;但更推荐改用 JsonResponse 包裹字典对象,或直接 HttpResponse(peak_data, content_type='application/json'),语义更清晰。
✅ 总结:前端处理 JSON API 的黄金法则是——一次 response.json(),全程操作 JS 对象。移除冗余的 JSON.stringify(),即可正常遍历 data.features、提取坐标与属性,实现地图渲染或数据驱动逻辑。










