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