You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.26 08:36:04