Leaflet加载PHP/MySQL生成的GeoJSON报错,JSONLint验证有效求助
我之前也碰到过类似的坑——明明JSONLint验证通过,Leaflet却死活报无效对象错误,折腾了好一阵才找到问题根源。给你几个实用的排查方向:
检查PHP输出的MIME类型
Leaflet对响应的内容类型很敏感,PHP输出GeoJSON时一定要先设置正确的HTTP头:header('Content-Type: application/json; charset=utf-8');如果没设置,服务器默认可能返回
text/html,哪怕JSON结构正确,Leaflet也会因为解析方式不对报错。排查输出是否有多余字符
很多时候PHP脚本会在JSON前后输出多余内容,比如:<?php标签前的空格、脚本末尾?>后的换行、调试用的echo语句、甚至PHP的警告信息。这些内容会让原本合法的JSON变得不纯净,Leaflet自然解析失败。你可以用浏览器开发者工具的Network面板,查看请求的原始响应内容,复制下来再去JSONLint验证,大概率能发现问题。确认坐标顺序是否正确
GeoJSON规范里坐标必须是**[经度, 纬度]**,很多人习惯写成[纬度, 经度],虽然JSONLint会认为结构合法,但Leaflet会判定为无效的地理对象。这个细节很容易忽略,一定要核对坐标顺序。检查GeoJSON的顶级结构
Leaflet只接受合法的GeoJSON顶级对象:要么是FeatureCollection(包裹多个Feature),要么是单个Feature或Geometry。如果你的PHP直接输出了一个Feature数组(没有外层的type: "FeatureCollection"和features属性),哪怕每个Feature都正确,Leaflet也会报错。测试静态GeoJSON是否正常加载
把你在JSONLint验证通过的GeoJSON内容,直接写进JS代码里作为静态数据加载:const validGeoJSON = { "type": "FeatureCollection", "features": [/* 你的Feature内容 */] }; L.geoJSON(validGeoJSON).addTo(map);如果这样能成功加载,说明问题出在PHP的输出环节,而不是GeoJSON本身;如果还是报错,那可能是JSONLint没检测到的类型错误(比如某个属性本该是数字却成了字符串)。
验证响应的编码格式
确保PHP输出的JSON是UTF-8编码,避免乱码干扰解析。除了在header里指定charset=utf-8,还要确认MySQL数据库的编码也是UTF-8,查询数据时不会出现乱码。
内容的提问来源于stack exchange,提问作者Adam

