散景server_document脚本从IP(HTTP)加载,但不从域(HTTPS)加载

时间:2019-05-11 13:00:25

标签: python nginx flask bokeh gunicorn

我在Flask和Gunicorn中嵌入了一个Bokeh应用程序(请参见flask_gunicorn_embed.py)。当我通过Web服务器的IP地址访问所有内容时,此方法工作正常,但当所有内容均通过Nginx代理时,此方法效果很好。它将从Flask中加载所有内容,但不会从Bokeh(autoload.js)中加载所有内容。


示例:

我通过Gunicorn开始烧瓶

gunicorn --workers 9 --bind 0.0.0.0:5000 --timeout 120 --log-file /some/directory/to/gunicorn/logs/gunicorn.log -m 0700 flask:app

我现在可以访问从Flask到 http://xxx.xxx.xxx.xxx:5000 的所有内容。我修改了 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开始烧瓶

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 documentation中给出的配置相同。该文档说要使用--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不会。

1 个答案:

答案 0 :(得分:0)

use_xheaders是Bokeh Server类的参数(它将其传递给龙卷风HTTPServer),而不是BokehTornado。如果您不是在自己ServerBokehTornado协调的情况下使用HTTPServer,那么您将在HTTP服务器上手动配置此选项,因为您没有{{ 1}}类为您做的事情:

Server