【问题标题】:Retain URL in browser with Flask redirect使用 Flask 重定向在浏览器中保留 URL
【发布时间】:2018-09-04 17:52:03
【问题描述】:

我在 Heroku 上部署了一个 Bokeh 服务器应用程序,具有多种样式,导致 URL 很麻烦。例如:https://invlabs-bokehserver.herokuapp.com/avyview?style=snowpacktracker

我正在使用部署在 Heroku 上的 Flask 从简单的自定义域 (www.snowpacktracker.com) 获取扩展,并重定向到运行 Bokeh 服务器并返回 html 内容的第二个 Heroku 应用程序。相关的 Flask 应用代码:

from flask import Flask, redirect

app = Flask(__name__)
@app.route('/')
def index():
  return redirect(url_for("btac"), code=302)

@app.route('/btac')
def func1():
  return redirect("https://invlabs-bokehserver.herokuapp.com/avyview?style=snowpacktracker", code=302)

@app.route('/btac/historic') 
def btac_historic():
  return redirect("https://invlabs-bokehserver.herokuapp.com/avyview", code=302)

if __name__ == '__main__':
  app.run()

我希望在 Flask 重定向发生时原始 URL 保持不变。 Flask 中是否有执行此操作的选项?或者我可以配置网络服务器来完成这个吗?

更新和更多细节:

我无法让 nginx 代理正常工作。我现在的情况:

www.snowpacktracker.com 被设置为运行 nginx + gunicorn + Flask 的 Heroku 应用程序的自定义域(使用 Heroku 提供的 DNS 目标)(这是一个可用于查看当前行为的工作链接)。此 Heroku 应用的基础 URL 是 https://snowpacktracker.herokuapp.com

当第一个 Heroku 应用收到请求时,Flask 应用会重定向到第二个运行 Bokeh 服务器的 Heroku 应用。按照目前的实现,您可以在浏览器中看到 URL 切换为 https://invlabs-bokehserver.herokuapp.com/avyview?style=snowpacktracker

www.snowpacktracker.comwww.snowpacktracker.com/btac 都重定向到同一个 URL。我用www.snowpacktracker.com/btac/historic 定义了第二种样式,它重定向到https://invlabs-bokehserver.herokuapp.com/avyview

我的目标是让页面加载 www.snowpacktracker.com(以及任何扩展名:/btac 或 /btac/historic)通过 Flask 重定向,如当前实施的那样,但原始 URL 保持不变。强>

我一直在尝试根据@Fian 的答案中的链接编辑nginx.conf.erb 配置文件中的location 块,但我没有运气。

location 块中的 proxy_passproxy_redirect(或 rewrite?)的正确语句是什么以实现此所需行为?

我当前的nginx配置文件(Heroku nginx build pack提供):

daemon off;
#Heroku dynos have at least 4 cores.
worker_processes <%= ENV['NGINX_WORKERS'] || 4 %>;

events {
    use epoll;
    accept_mutex on;
    worker_connections 1024;
}

http {
        gzip on;
        gzip_comp_level 2;
        gzip_min_length 512;

    server_tokens off;

    log_format l2met 'measure#nginx.service=$request_time request_id=$http_x_request_id';
    access_log logs/nginx/access.log l2met;
    error_log logs/nginx/error.log;

    include mime.types;
    default_type application/octet-stream;
    sendfile on;

    #Must read the body in 5 seconds.
    client_body_timeout 5;

    upstream app_server {
        server unix:/tmp/nginx.socket fail_timeout=0;
    }

    server {
        listen <%= ENV["PORT"] %>;
        server_name _;
        keepalive_timeout 5;

        location / {
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header Host $http_host;
            proxy_redirect off;
            proxy_pass http://app_server;
        }
    }
}

【问题讨论】:

    标签: nginx heroku flask bokeh nginx-config


    【解决方案1】:

    我认为你的“相关烧瓶代码”看起来有点多余,因为整个事情可以很容易地单独在 nginx 中实现,而不需要你提供的烧瓶代码。

    这样的事情可能会奏效:

    server_name .snowpacktracker.com;
    location = / {
        return 302 /btac;
    }
    location / {
        return 404;
    }
    location /static {
        proxy_pass http://invlabs-bokehserver.herokuapp.com;
    }
    location /avyview {
        proxy_pass http://invlabs-bokehserver.herokuapp.com;
    }
    location = /btac {
        proxy_pass http://invlabs-bokehserver.herokuapp.com/avyview?style=snowpacktracker;
    }
    location = /btac/historic {
        proxy_pass http://invlabs-bokehserver.herokuapp.com/avyview;
    }
    

    请注意,您的基础应用程序(invlabs-bokehserver.herokuapp.com/avyview)在多个实例中明确提及其自己的完整 URL,包括基于 JavaScript 的自动重定向到移动版本(即 window.location = 'https://btac-web-plots.herokuapp.com/avyview?style=snowpacktracker-mobile';);这显然会干扰您“隐藏”应用程序底层 URL 的愿望。

    【讨论】:

    • 我同意,Flask 重定向确实没有理由。我们现在已经开始沿着@Fian 建议的道路,“修改你的整个架构”。这涉及将 Bokeh 中的服务器文档嵌入到 Flask 模板中,而不是重定向到我们完全渲染的 Bokeh 文档。但是,如果我们需要依赖原始 URL 结构,我将使用您建议的方法。
    【解决方案2】:

    您想要的称为代理,可以通过nginxapache 实现。

    附:您的整个问题似乎很奇怪,请修改您的整个架构。

    【讨论】:

    • 谢谢,我会检查代理。我在 Heroku 上使用 nginx + gunicorn。是的,这实际上是一个临时解决方案,利用了我们已经编写的大量代码。尽管我们的架构可能需要进行重大修改,但时间和资金不足。
    • 我一直在尝试编辑 nginx 配置文件,但没有成功。我使用我的配置文件中的默认 location 块发布了更新和更多详细信息。
    【解决方案3】:

    我认为您对 http://nginx.org/r/proxy_redirect 的作用有误解。很明显,您试图将其设置为 off 以避免将面向用户的重定向(例如 301302 Moved)返回给用户,从而泄露内部域名,但是这与指令的作用完全相反——几乎总是最好将其保留为默认值。

    如果您希望 URL 保持不变,只需使用 http://nginx.org/r/proxy_pass

    【讨论】:

    • 您能否为location 块提出更具体的建议?我一直在为proxy_pass 尝试各种参数,但没有成功。
    • 您在原始问题中的内容看起来很合理。您可能想尝试删除 proxy_set_header Host $http_host; 部分 - 除非您的上游确实需要下游的主机名。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-06-26
    • 2020-12-27
    • 2012-12-01
    • 1970-01-01
    • 2012-12-01
    • 2016-04-30
    • 1970-01-01
    相关资源
    最近更新 更多