python - Bokeh server_document 脚本从 IP (HTTP) 加载,但不从域 (HTTPS) 加载
问题描述
我在 Flask 和 Gunicorn 中嵌入了一个 Bokeh 应用程序(请参阅flask_gunicorn_embed.py)。当我通过 Web 服务器的 IP 地址访问所有内容时,这可以正常工作,但当所有内容都通过 Nginx 代理时就不行了。它将从 Flask 加载所有内容,但不会从 Bokeh (the autoload.js
) 加载。
例子:
我通过 Gunicorn 启动 Flask
gunicorn --workers 9 --bind 0.0.0.0:5000 --timeout 120 --log-file /some/directory/to/gunicorn/logs/gunicorn.log -m 0700 flask:app
我现在可以通过http://xxx.xxx.xxx.xxx:5000从 Flask 访问所有内容。我已经改编了flask_gunicorn_embed.py,最重要的部分是
script = server_document('http://xxx.xxx.xxx.xxx:%d/bkapp' % port, resources=None)
sockets, port = bind_sockets("0.0.0.0", 0)
bokeh_tornado = BokehTornado({'/bkapp': bkapp}, extra_websocket_origins=["xxx.xxx.xxx.xxx:5000"])
如果我现在访问使用此 Bokeh 服务器的页面,一切正常。它加载
http://xxx.xxx.xxx.xxx:XXXXX/bkapp/autoload.js?bokeh-autoload-element=1001&bokeh-app-path=/bkapp&bokeh-absolute-url=http://xxx.xxx.xxx.xxx:XXXXX/bkapp&resources=none
并显示图形,并为回调创建一个 Web 套接字。
这没有Nginx 作为反向代理。我不想使用 Web 服务器的 IP 地址,因为我需要使用 HTTPS,它需要一个域。
因此,我有以下 Nginx 配置:
server {
listen 80;
server_name example.com;
return 301 https://$server_name/;
}
server {
listen 443;
server_name example.com;
ssl on;
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
client_max_body_size 50M;
location / {
include proxy_params;
proxy_pass http://127.0.0.1:5000;
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;
}
location /static {
alias /some/directory/to/flask/static;
}
}
我通过 Gunicorn 启动 Flask
gunicorn --workers 9 --bind 127.0.0.1:5000 --timeout 120 --log-file /some/directory/to/gunicorn/logs/gunicorn.log -m 0700 flask:app
我现在可以通过https://example.com从 Flask 访问所有内容。flask_gunicorn_embed.py现在看起来像
script = server_document('https://example.com:%d/bkapp' % port, resources=None)
sockets, port = bind_sockets("0.0.0.0", 0)
bokeh_tornado = BokehTornado({'/bkapp': bkapp}, extra_websocket_origins=["example.com"])
但是,通过 Bokeh 生成的每个请求server_document
https://example.com:XXXXX/bkapp/autoload.js?bokeh-autoload-element=1001&bokeh-app-path=/bkapp&bokeh-absolute-url=https://example.com:XXXXX/bkapp&resources=none
导致连接超时或连接被拒绝,因此不加载脚本。
我怎样才能让它连接并加载脚本?
它一定与 Nginx 有关,因为如果我通过 IP 地址请求文件,它仍然可以工作(由于bind_sockets("0.0.0.0", 0)
. 但我无法弄清楚是什么导致了这个问题。
编辑:
它使用 HTTPS 似乎是一个问题。我的 Nginx 配置与Bokeh 文档中给出的配置相同。文档说要使用--use_xheaders
,这是不可能的,因为我没有使用bokeh serve
。
我有
conf = {'use_xheaders': True}
bokeh_tornado = BokehTornado({'/bkapp': bkapp}, extra_websocket_origins=["example.com"], **conf)
bokeh_http = HTTPServer(bokeh_tornado, xheaders=True)
但它仍然不会加载 HTTPS 页面的脚本。
http://example_no_https.com将通过端口加载页面,而https://example.com不会。
解决方案
use_xheaders
是 BokehServer
类的参数(将其传递给 Tornado HTTPServer
),而不是 by BokehTornado
。如果您不使用Server
是因为您正在协调BokehTornado
并且您HTTPServer
自己,那么您将在 HTTP 服务器上手动配置此选项,因为您没有一个Server
类为您执行此操作:
http_server_kwargs.setdefault('xheaders', opts.use_xheaders)
HTTPServer(..., **http_server_kwargs)
推荐阅读
- java - RestEasy JUnit Test:测试外部 API 是否正在使用 JUnit 测试
- blazor-webassembly - Blazor WASM:.NET CORE 6 RC1 Invalid /api 路由返回 HTML 而不是 NOT Found
- c# - 如何在 OS(win10) 中跟踪焦点窗口或覆盖现有窗口?
- video - 如何重播 RTSP 流并支持暂停、速度调整和倒带?
- r - 如何在R中的数据框中列出给定名称的多个值的最小值和最大值?
- node.js - ReferenceError:_user 未在 \routes\user.js:35:13 中定义
- python - 有没有一种简单的方法来改变 pandas 打印整数空值的方式?
- r - 在 R 中使用 map 函数进行过滤
- javascript - Wordpress 设置页面如何有条件地使用 add_settings_field 添加禁用的字段?
- node.js - 如何将反应客户端和快速服务器部署到 GCP?