为什么嵌入页面的 Bokeh server 应用加载失败:父页面与 Bokeh server 的 HTTP/HTTPS 协议不匹配

发布时间:2026/9/15 19:47:18
为什么嵌入页面的 Bokeh server 应用加载失败:父页面与 Bokeh server 的 HTTP/HTTPS 协议不匹配 为什么嵌入页面的 Bokeh server 应用加载失败父页面与 Bokeh server 的 HTTP/HTTPS 协议不匹配【免费下载链接】bokehInteractive Data Visualization in the browser, from Python项目地址: https://gitcode.com/GitHub_Trending/bo/bokeh当 Bokeh server 应用通过bokeh.embed的server_document或server_session嵌入到更大的网站交易平台的趋势线图、库存系统里的 Bokeh 视图时你会遇到这样一种故障父页面本身能正常打开但嵌入的 Bokeh 内容始终加载不出来。Bokeh 官方部署文档给出的结论很明确——父服务与 Bokeh server 一个走 HTTPS、另一个走 HTTP或反过来时Bokeh 的 loader 脚本向 Bokeh server 发起的请求会失败嵌入的应用也就无法显示。本文说明这个失败的机制、如何确认是协议不匹配以及文档给出的两种让两侧协议一致的配置方式。loader 如何决定向 Bokeh server 发起哪种协议的请求server_document返回的script标签会加载 Bokeh server 上的 autoload 资源。以文档中的示例为例调用from bokeh.embed import server_document script server_document(https://demo.bokeh.org/sliders)生成的标签文档示例输出形如script srchttps://demo.bokeh.org/sliders/autoload.js?bokeh-autoload-element1000bokeh-app-path/slidersbokeh-absolute-urlhttps://demo.bokeh.org/sliders id1000 /script部署文档deploy.rst原文警告Do not run Bokeh server over HTTP while running the parent service over HTTPS, or vice-versa. Bokehs loader code determines which protocol to load resources over on the client-side, viawindow.location.protocol, so if the protocol of the parent service does not match the protocol of your Bokeh server instance, the loader scripts requests to Bokeh server will fail.也就是说协议决策发生在客户端。对照 BokehJS 源码 bokehjs/src/lib/embed/server.tsserver_document场景下 loader 拿到的是server_document传入的应用绝对 URL随后按该 URL 的协议选择 WebSocket 协议const protocol loc.protocol https: ? wss: : ws: // ... return ${protocol}//${loc.host}${app_path}/ws注意这里有一个容易被忽略的点server_document的 URL 是应用自身的绝对地址它的协议与父页面的协议是两个独立配置。典型失败组合是——父页面已经通过 CDN/网关走了 HTTPS而 Bokeh server 仍以纯 HTTP 形式暴露例如http://bokeh.internal:5006/myapp。页面是 HTTPS 的但页面里的脚本要求浏览器去连一个 HTTP 地址浏览器按混合内容策略拦截加载中断嵌入区域空白。反向组合父页面 HTTP、Bokeh server HTTPS同样触发文档警告中的失败只是较少见。先确认是协议不匹配而不是其他原因排查时依次核对两点把故障定位到协议问题分别确认两个 URL 的协议父页面在浏览器地址栏中的地址例如https://acme.com/productsserver_document/server_session第一个参数传入的 Bokeh server 应用 URL例如http://bokeh.internal:5006/myapp。 两者前缀一个是https://、另一个是http://就命中本文描述的故障。确认嵌入方式确实走的是 server 应用。只有server_document和server_session需要 Bokeh server 并保持 WebSocket 长连接file_html、components、json_item、autoload_static这类独立文档嵌入不依赖 Bokeh server不存在本问题参见 embed.rst。同时要注意一个容易混淆的相邻故障如果浏览器控制台里 Bokeh server 返回的是HTTP 403那通常不是协议不匹配而是请求的Origin头不在允许的 WebSocket origin 列表里。Bokeh server 默认只允许localhost:5006嵌入到其他站点时必须通过--allow-websocket-origin显式放行父页面域名bokeh serve --show --allow-websocket-originacme.com myapp.py多个来源可以重复传多次--allow-websocket-origin。放行范围只应限于你自己的父页面域名--allow-websocket-origin*会接受任意来源文档明确说这只适合测试、实验和本地 notebook。修复方式一让 Bokeh server 直接提供 HTTPSSSL 终止如果父页面是 HTTPS最直接的做法是让 Bokeh server 自身终止 SSL直接提供 HTTPS 与 WSS 会话。按 deploy.rst 的说明提供--ssl-certfile参数值为单个 PEM 文件路径包含证书以及建立证书真实性所需的 CA 证书bokeh serve myapp.py --ssl-certfile /path/to/cert.pem证书路径也可以通过环境变量BOKEH_SSL_CERTFILE提供。如果私钥单独存放用--ssl-keyfile参数或BOKEH_SSL_KEYFILE环境变量指定私钥带密码时通过BOKEH_SSL_PASSWORD环境变量提供。配置完成后把server_document的应用 URL 改成对应的https://地址与父页面协议保持一致。修复方式二Nginx 反向代理终止 SSLBokeh server 加--use-xheaders另一种文档给出的拓扑Bokeh server 保持 HTTP 运行在内网由 Nginx 在前面终止 SSL。这种部署必须给 Bokeh server 加--use-xheaders标志否则 Bokeh 无法从代理头中得知真实的外部协议bokeh serve myapp.py --port 5100 --use-xheaders文档对--use-xheaders的解释它会用X-Real-Ip、X-Forwarded-For、X-Scheme、X-Forwarded-Proto请求头当这些头存在时覆盖所有请求的远端 IP 和 URI scheme/协议。对应的 Nginx 侧要求配置 SSL 终止并转发X-Forwarded-Proto头可选地把 HTTP 流量 301 重定向到 HTTPS。文档给出的是参考配置其中foo.com、证书路径都是示意值按你的域名和证书实际位置替换# redirect HTTP traffic to HTTPS (optional) server { listen 80; server_name foo.com; return 301 https://$server_name$request_uri; } server { listen 443 default_server; server_name foo.com; add_header Strict-Transport-Security max-age31536000; ssl on; # SSL installation details vary by platform ssl_certificate /etc/ssl/certs/my-ssl-bundle.crt; ssl_certificate_key /etc/ssl/private/my_ssl.key; ssl_protocols TLSv1 TLSv1.1 TLSv1.2; ssl_ciphers ECDHE-RSA-AES256-GCM-SHA384:...; ssl_prefer_server_ciphers on; location / { proxy_pass http://127.0.0.1:5100; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection upgrade; proxy_http_version 1.1; proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header Host $host:$server_port; proxy_buffering off; } }这段配置会把所有到foo.com的 HTTPS 连接代理到内网的http://127.0.0.1:5100。此时server_document里传入的应用 URL 应写成 Nginx 暴露的https://公共地址而不是内网 HTTP 地址。注意ssl on、TLS 协议与密码套件列表是文档原文的参考写法证书安装细节因平台而异以你的平台为准。如果 Bokeh server 运行在另一个 Python 应用中程序化Server对应的环境变量如BOKEH_SSL_CERTFILE可通过Server.from_settings工厂方法读取见 library.rst。验证与配套检查协议对齐之后按以下顺序验证在浏览器中打开父页面确认嵌入区域能正常渲染 Bokeh 应用并可用工具、交互生效而不是停留在空白或加载失败。对照文档警告的失败模式修复前是 loader 请求 Bokeh server 失败修复后这一环节应当通过。确认server_document/server_session的应用 URL 与父页面地址栏前缀一致同为https://。检查父服务的 content security policyCSP是否放行了 Bokeh server部署文档要求把 Bokeh server 的公网主机名和端口加入父服务 CSP 的script-src与connect-src指令HTTP(S) 和 WS(S) 协议都要覆盖。具体配置方式取决于父服务所用的框架参考对应框架的文档文档也把用反向代理覆写 CSP 头列为最后手段。CSP 拦截时同样表现为页面能打开、嵌入内容加载不出来容易与协议不匹配混淆建议一并确认。若之前为了调试临时把--allow-websocket-origin设成了*上线前改回精确的父页面域名避免其他站点在不知情的情况下嵌入你的应用。两条修复路径选其一即可Bokeh server 直接终止 SSL 适用于想减少中间层的情况Nginx 终止 SSL 加上--use-xheaders适用于本来就要用反向代理暴露服务的场景。无论哪种判定标准只有一条——父页面与server_document应用 URL 的协议前缀一致loader 对 Bokeh server 的请求不再失败。【免费下载链接】bokehInteractive Data Visualization in the browser, from Python项目地址: https://gitcode.com/GitHub_Trending/bo/bokeh创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

关于本文作者

来自尧图内容编辑团队

尧图内容编辑团队 内容团队

尧图内容编辑团队

本文由尧图网络内容编辑团队执笔。团队由资深项目经理、前端工程师与设计师组成,所有内容均来自亲手交付的真实项目,先讲清问题、再给出可落地的解法。尧图深耕北京网站建设十年,服务过京华建材集团、智造科技等各行业客户,把一线经验沉淀为可复用的行业观察。

  • 十年建站经验,覆盖建材、制造、服务、文创等
  • 项目经理把关选题与事实准确性
  • 工程师与设计师联合撰写专业细节
  • 统一编辑规范,保证文风与排版一致
  • 每月复盘转化数据,迭代选题方向

延伸阅读

相关资讯与近期热门内容

深度阅读推荐

建站决策前值得细读的三篇

网站改版的5个关键决策
2024-08-12

网站改版的5个关键决策

什么时候该改版、改到什么程度、如何避免流量掉光,京华建材集团改版复盘给出答案。

获取专属建站方案

看完文章,把您的行业与预算告诉我们,免费获取一份量身定制的官网建设方案与报价。

立即免费咨询