vertx 应用程序中的 CORS 问题不起作用

Sau*_*gol 5 javascript java cors vert.x

我的 Vertx 服务器驻留在服务器 A 中,客户端驻留在服务器 B 中。当我尝试访问 vertx 服务器时,出现 CORS 错误。我添加了一些服务器端代码来处理 CORS 问题,但它不起作用。我们是否需要在客户端添加一些标头。我在这里错过了什么?谁能帮忙

顶点服务器端:

Router router = Router.router(vertx);
router.route().handler(BodyHandler.create());
router.route().handler(io.vertx.rxjava.ext.web.handler.CorsHandler.create("*")
.allowedMethod(io.vertx.core.http.HttpMethod.GET)
.allowedMethod(io.vertx.core.http.HttpMethod.POST)
.allowedMethod(io.vertx.core.http.HttpMethod.OPTIONS)
.allowedHeader("Access-Control-Request-Method")
.allowedHeader("Access-Control-Allow-Credentials")
.allowedHeader("Access-Control-Allow-Origin")
.allowedHeader("Access-Control-Allow-Headers")
.allowedHeader("Content-Type"));
Run Code Online (Sandbox Code Playgroud)

客户端实现:

    function(url, user) {
    eventBus = new EventBus(url);
    eventBus.onopen = function() {
            //Do Something
    }
 }
Run Code Online (Sandbox Code Playgroud)

更新:

我删除了标题中的 withCredential 属性。现在我的代码看起来像

if (ar.succeeded()) {
routingContext.response().setStatusCode(200).setStatusMessage("OK")
.putHeader("content-type", "application/json")
.putHeader("Access-Control-Allow-Origin", "*")
.putHeader("Access-Control-Allow-Methods","GET, POST, OPTIONS")
.end(
Json.encodePrettily(ar.result().body())
//(String) ar.result().body()
);
routingContext.response().close(); 
Run Code Online (Sandbox Code Playgroud)

但仍然弹出以下错误。你能帮我吗?

XMLHttpRequest cannot load https://192.168.1.20:7070/Notify/571/rn4nh0r4/xhr_send?t=1471592391921. A wildcard '*' cannot be used in the 'Access-Control-Allow-Origin' header when the credentials flag is true. Origin 'https://login.com' is therefore not allowed access. The credentials mode of an XMLHttpRequest is controlled by the withCredentials attribute.
Run Code Online (Sandbox Code Playgroud)

更新2: 添加我的客户地址后

.putHeader("Access-Control-Allow-Origin", "*")
Run Code Online (Sandbox Code Playgroud)

我得到以下日志:

XMLHttpRequest cannot LOAD https://192.168.1.20:7070/Notify/773/k3zq1z2z/xhr_send?t=1471601521206. Credentials flag IS 'true', but the 'Access-Control-Allow-Credentials' header IS ''. It must be 'true' TO allow credentials. Origin 'https://login.com' IS therefore NOT allowed access.
Run Code Online (Sandbox Code Playgroud)

我的代码如下:

 if (ar.succeeded()) {
routingContext.response().setStatusCode(200).setStatusMessage("OK")
.putHeader("content-type", "application/json")
.putHeader("Access-Control-Allow-Origin", "https://login.com")
.putHeader("Access-Control-Allow-Methods","GET, POST, OPTIONS")
.putHeader("Access-Control-Allow-Credentials", "true")
.end(
Json.encodePrettily(ar.result().body())
//(String) ar.result().body()
);
routingContext.response().close();
Run Code Online (Sandbox Code Playgroud)

Ale*_*hin 7

那是因为在定义路由时顺序很重要。只需在 CORS 和 BodyHandler 之间切换:

Router router = Router.router(vertx);
router.route().handler(io.vertx.rxjava.ext.web.handler.CorsHandler.create("*")
.allowedMethod(io.vertx.core.http.HttpMethod.GET)
.allowedMethod(io.vertx.core.http.HttpMethod.POST)
.allowedMethod(io.vertx.core.http.HttpMethod.OPTIONS)
.allowedHeader("Access-Control-Request-Method")
.allowedHeader("Access-Control-Allow-Credentials")
.allowedHeader("Access-Control-Allow-Origin")
.allowedHeader("Access-Control-Allow-Headers")
.allowedHeader("Content-Type"));
router.route().handler(BodyHandler.create());
Run Code Online (Sandbox Code Playgroud)


Rud*_*dyD 5

I had the same problem and was finally able to solve it. You will need to provide a valid regex String to CorsHandler.create("Regex String Here"). So if you want to allow any protocol:host:port, aka "*", through CORS handling you can use.

router.route().handler(CorsHandler.create(".*.")  //note the "." surrounding "*"
Run Code Online (Sandbox Code Playgroud)

If you want a fine-grained control of allowed protocol:host:port, you have flexibility with the Regex String. Example: CORS handling for either http:// or https:// from localhost and any port will look like this:

router.route().handler(CorsHandler.create("((http://)|(https://))localhost\:\d+")  
.allowedMethod(HttpMethod.GET)
.allowedMethod(HttpMethod.POST)
.allowedMethod(HttpMethod.OPTIONS)
.allowCredentials(true)
.allowedHeader("Access-Control-Allow-Method")
.allowedHeader("Access-Control-Allow-Origin")
.allowedHeader("Access-Control-Allow-Credentials")
.allowedHeader("Content-Type"));  //makes sure you add other headers expected in the request
Run Code Online (Sandbox Code Playgroud)

To allow a list of specific clients only, you can concatenate with an OR operator "|" in your regex string.

router.route().handler(CorsHandler.create("http://localhost:8080" | "https://128.32.24.45:\\d+"))
Run Code Online (Sandbox Code Playgroud)


Sau*_*gol 4

通过在路由器处理程序中将 withCredential 标志添加为 true 解决了该问题。

我的代码如下

router.route().handler(io.vertx.rxjava.ext.web.handler.CorsHandler.create("https://login.com")
.allowedMethod(io.vertx.core.http.HttpMethod.GET)
.allowedMethod(io.vertx.core.http.HttpMethod.POST)
.allowedMethod(io.vertx.core.http.HttpMethod.OPTIONS)
.allowCredentials(true)
.allowedHeader("Access-Control-Allow-Method")
.allowedHeader("Access-Control-Allow-Origin")
.allowedHeader("Access-Control-Allow-Credentials")
.allowedHeader("Content-Type"));
Run Code Online (Sandbox Code Playgroud)

以前它仅在响应标头中设置

if (ar.succeeded()) {
routingContext.response().setStatusCode(200).setStatusMessage("OK")
.putHeader("content-type", "application/json")
.putHeader("Access-Control-Allow-Origin", "https://login.com")
.putHeader("Access-Control-Allow-Methods","GET, POST, OPTIONS")
.putHeader("Access-Control-Allow-Credentials", "true")
.end(
Json.encodePrettily(ar.result().body())
//(String) ar.result().body()
);
routingContext.response().close();
Run Code Online (Sandbox Code Playgroud)