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

时间:2015-12-01 14:05:31

标签: javascript ajax cors haproxy

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

这是Web应用程序正确可视化的问题"维护模式"根据被拒绝的后端请求(使用503),因为浏览器首先发送OPTIONS请求(预检)并且已经获得503。这最终导致浏览器没有将此状态代码反映到JavaScript中执行的ajax调用(我们始终将状态代码0作为响应,因为浏览器将其解释为预检的致命故障并拒绝任何访问)。 这个故事不是新的,stackoverflow上有很多帖子。

那么如何解决这个问题呢? 我的想法是提供两个不同的错误文件("错误文件"在HAproxy语言中) - 一个用内容提供OPTIONS请求" HTTP / 1.1 200 OK ....访问 - Control-Allow-Origin:* ...."在浏览器中传递预检检查,然后一个错误文件服务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

我知道这不起作用,因为 errorfile 不允许使用if <condition>变体。

如何实现我希望的行为?如果有人有另一种解决方案来解决这个问题&#34; Maintanace Mode&#34; / CORS问题,我对任何想法持开放态度......

提前致谢!

1 个答案:

答案 0 :(得分:4)

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

  • 定义两个“后端”(因此将“listen”部分拆分为“frontend”和“backend”
  • “frontend”部分检查请求方法,并使用一个“后端”来回答OPTIONS请求,使用一个“后端”来回答所有其他请求。
  • 第一个定义的“后端”用于回答200的所有OPTIONS请求:这可以使用错误文件来完成,如果我们没有列出本节中的任何服务器,则此“后端”被标记为“关闭”并因此响应errorfile(我们将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 ...


options.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]


503.http

HTTP/1.1 503 Service Unavailable
Cache-Control: no-cache
Access-Control-Allow-Origin: *
Connection: close
[empty line]

还有一个额外的冒险:此配置由HAproxy自动提供所有OPTIONS请求 - 即使支持CORS!