我们有一个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


我知道这是行不通的,因为错误文件不允许if <condition>变体。

如何实现我的期望行为?如果有人有其他解决方案来解决此“维护模式” / CORS问题,那么我很乐意...

提前致谢!

最佳答案

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


定义两个“后端”(因此将“侦听”部分分为“前端”和“后端”
“前端”部分检查请求方法,并使用一个“后端”来回答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 ...



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支持!

09-28 10:45