PySide2 QWebEngineView加载Folium生成的HTML时不显示OpenStreetMap底图
问题根因
这个故障和PySide2/PyQt5、Folium的版本更新无关,核心触发原因是OpenStreetMap(OSM)近期调整了瓦片服务的安全校验规则:
- OSM在2024年中上线了请求拦截逻辑,会直接拒绝所有不携带合法Referer头、或Referer来源为本地
file://协议的瓦片请求,目的是遏制批量爬虫对公开服务的滥用 - QWebEngineView加载本地保存的
file://协议HTML文件时,默认安全策略会自动屏蔽请求的Referer字段,导致所有发往OSM瓦片域名的请求都被服务端拦截,拿不到底图瓦片资源 - 地图上的叠加图标是页面JS直接渲染的本地元素,不需要跨域请求外部资源,因此不受拦截影响,也就出现了“只显示图标、不显示底图”的现象
验证匹配逻辑
你可以通过已观测到的现象交叉验证这个结论:
- 用系统普通浏览器直接打开生成的HTML文件能正常显示底图:桌面浏览器对本地file页面发起的跨域请求,会自动携带符合OSM校验要求的Referer头,不会被拦截
- 切换MapBox等其他第三方底图源后程序恢复正常:这类底图服务没有针对本地file协议来源的请求做Referer拦截
- 升级PySide2、Folium版本后故障没有变化:问题既不在GUI框架的功能逻辑,也不在前端HTML的生成代码上
实用解决办法
方案1:定制QWebEngine请求拦截器(零侵入业务代码)
直接在Web引擎层面给所有发往OSM的请求补上合法的Referer头,不需要修改生成的HTML文件:
from PySide2.QtWebEngineCore import QWebEngineUrlRequestInterceptor class OSMTileRequestInterceptor(QWebEngineUrlRequestInterceptor): def interceptRequest(self, request_info): # 匹配所有OSM瓦片域名的请求,补充合法Referer头 if "tile.openstreetmap.org" in request_info.requestUrl().host(): request_info.setHttpHeader(b"Referer", b"https://www.openstreetmap.org/") # 在Browser类初始化时绑定拦截器即可 def __init__(self): super().__init__() # ... 原有初始化逻辑 self.view = QWebEngineView() # 绑定请求拦截器到当前页面 request_interceptor = OSMTileRequestInterceptor(self.view.page()) self.view.page().setUrlRequestInterceptor(request_interceptor)
注意:不要尝试通过清理QWebEngine缓存、降级框架版本解决这个问题,这类操作无法修改请求头的发送逻辑,对OSM的服务端拦截没有任何效果。
方案2:用本地临时HTTP服务替代file协议加载
如果不想修改Web引擎的请求配置,可以用Python内置的HTTP服务把本地HTML托管到http://127.0.0.1地址下加载,这种模式下发起的跨域请求会自动携带合法的localhost来源标识,能通过OSM的校验:
from http.server import HTTPServer, SimpleHTTPRequestHandler import threading # 后台启动随机端口的本地临时HTTP服务 local_server = HTTPServer(("127.0.0.1", 0), SimpleHTTPRequestHandler) local_port = local_server.server_address[1] threading.Thread(target=local_server.serve_forever, daemon=True).start() # 加载页面时替换原file://地址为本地HTTP地址 self.view.load(QUrl(f"http://127.0.0.1:{local_port}/placeholder.html"))
方案3:替换无拦截的OSM镜像源
如果不需要固定使用官方OSM瓦片,可以在Folium生成地图的时候,直接把默认的OSM瓦片地址替换成公开的、无Referer拦截的OSM镜像节点,不需要修改GUI程序的任何逻辑。
内容的提问来源于stack exchange,提问作者spareTimeCoder
相关产品推荐
相关产品推荐

