HAproxy:OPTIONS 和 POST 方法的 503 错误文件不同

bad*_*era 1 javascript ajax haproxy cors

我们有一个 Web 应用程序,使用 ajax 调用运行在不同域上的后端(-> 需要 CORS)。后端由HAproxy 1.4.22组成和多个 Wildfly(在 OpenShift PaaS 上运行)组成。如果没有 Wildfly 可用(例如,在“维护”期间),HAproxy 会为每个请求或配置的错误文件提供 503 服务。到目前为止,一切都很好...

对于 Web 应用程序来说,根据被拒绝的后端请求(带有 503)正确可视化“维护模式”是一个问题,因为浏览器首先发送一个 OPTIONS 请求(预检)并已收到 503。这最终导致浏览器不会将此状态代码反映到 JavaScript 中执行的 ajax 调用(我们总是得到状态代码 0 作为响应,因为浏览器将其解释为预检的致命失败并拒绝任何访问)。这个故事并不新鲜,在 stackoverflow 上有很多帖子。

那么如何解决这个问题呢?我的想法是提供两个不同的错误文件(HAproxy 语言中的“错误文件”) - 一个提供内容为“HTTP/1.1 200 OK.... Access-Control-Allow-Origin: *....”的 OPTIONS 请求以传递在浏览器中进行预检,然后一个错误文件为 POST 请求提供内容“HTTP/1.1 503 .....”,让浏览器在 ajax 响应中真正反映状态 503。但是,我无法运行它。

global
    maxconn     256

defaults
    mode                    http
    log                     global
    option                  httplog
    ...

listen express 127.4.184.2:8080
    acl is_options method OPTIONS
    acl is_post method POST

    errorfile 503 /var/lib/openshift/564468c90c1e66c7f2000077/app-root/runtime/repo/503.http if is_post
    errorfile 503 /var/lib/openshift/564468c90c1e66c7f2000077/app-root/runtime/repo/options.http if is_options

    option httpchk GET /
    http-check expect rstatus 2..|3..|401

    balance leastconn
    server local-gear 127.4.184.1:8080 check fall 2 rise 3 inter 2000 cookie local-564468c90c1e66c7f2000077
Run Code Online (Sandbox Code Playgroud)

我知道这不起作用,因为错误文件不允许该if <condition>变体。

我怎样才能实现我想要的行为?如果有人有另一种解决方案来解决这个“维护模式”/CORS 问题,我愿意接受任何想法......

提前致谢!

bad*_*era 5

我找到了一个很好的解决方案:

  • 定义两个“后端”(因此将“监听”部分分为“前端”和“后端”
  • “前端”部分检查请求方法,并使用一个“后端”来应答 OPTIONS 请求,并使用一个“后端”来应答所有其他请求。
  • 第一个定义的“后端”用于用 200 应答所有 OPTIONS 请求:这可以通过错误文件来完成,如果我们在本节中没有列出任何服务器,则该“后端”被标记为 Down 并响应,因此错误文件(在我们将 200 发送回 OPTIONS 请求)。
  • 第二个定义的“后端”保留为“真实”后端并响应(以防真实服务器关闭)以及错误文件中的内容。
  • 在错误文件中,我们可以添加 CORS 标头。


HAproxy.cfg

global
     maxconn     256

defaults
    mode                    http
    log                     global
    option                  httplog
    option                  dontlognull
    maxconn                 128
    ...

frontend balancer
    bind 127.8.155.130:8080
    mode http
    acl is_options method OPTIONS
    use_backend cors_backend if is_options
    default_backend business_backend

backend cors_backend
    errorfile 503 options.http

backend business_backend
    errorfile 503 503.http
    server ...
    server ...
Run Code Online (Sandbox Code Playgroud)


选项.http

HTTP/1.1 200 OK
Access-Control-Allow-Headers: Origin, Accept, X-Session_id, Content-Type
Access-Control-Allow-Origin: *
Access-Control-Allow-Credentials: true
Access-Control-Max-Age: 86400
Access-Control-Allow-Methods: HEAD, DELETE, POST, GET, OPTIONS, PUT
Connection: close
[empty line]
Run Code Online (Sandbox Code Playgroud)


503.http

HTTP/1.1 503 Service Unavailable
Cache-Control: no-cache
Access-Control-Allow-Origin: *
Connection: close
[empty line]
Run Code Online (Sandbox Code Playgroud)

还有一个额外的优点:此配置由 HAproxy 自动处理所有 OPTIONS 请求 - 即使有 CORS 支持!