how to enable CORS with Vert.x 2.x

2019-02-17 23:41发布

问题:

I am trying to make cross-domain requests with Angularjs 1.4.5. But can't get success. I have configured $httpprovider

.config(['$httpProvider', function($httpProvider) {
        $httpProvider.defaults.useXDomain = true;
        delete $httpProvider.defaults.headers.common['X-Requested-With'];
        $httpProvider.defaults.headers.common['Accept']= "application/json, text/plain, */*";
        $httpProvider.defaults.headers.put["Content-Type"] = "application/x-www-form-urlencoded;charset=utf-8";
        $httpProvider.defaults.headers.post["Content-Type"] = "application/x-www-form-urlencoded;charset=utf-8";
        $httpProvider.interceptors.push('authenticationFailedInterceptor');
    }])

But still con't get success. How to enable CORS support with Vert.x 2.x http server.

CORS is supported in Vert.x 3.x but Right now I can't upgrade Vert.x.

回答1:

have you tried with something like this on your responses?

vertx.createHttpServer()
  .requestHandler(function (req) {
    req.response()
      .putHeader("content-type", "text/plain")
      .putHeader("Access-Control-Allow-Origin", "*")
      .putHeader("Access-Control-Allow-Methods", "GET, POST, OPTIONS");
      .putHeader("Access-Control-Allow-Headers", "Content-Type, Authorization");
      .end("Hello from Vert.x!");
}).listen(8080);

for sure, you have to modify this to your needs... but the changes has to be done in the server and at least, you need these three headers.



回答2:

Complete example to enable cors:

We need to create two route matcher.

One helps to enable cors and other handle the requests.

Below is to enable cors. It Accept all request and add all the required headers needs to enable cors. After that we need to hand over request to the actual route matcher to handle request. We have that by the name secureRoutes.

RouteMatcher routeMatcher = new RouteMatcher();
        routeMatcher.options(".*",new Handler<HttpServerRequest>() {
            @Override
            public void handle(final HttpServerRequest request) {
                request.response().putHeader("Access-Control-Allow-Origin", "*");
                request.response().putHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE");
                request.response().putHeader("Access-Control-Allow-Headers", "accept, authorization, content-type, email");
                request.response().end();
            }
        })
        .all(".*",new Handler<HttpServerRequest>() {
            @Override
            public void handle(final HttpServerRequest request) {
                request.response().putHeader("Access-Control-Allow-Origin", "*");
                secureRoutes.getRouteMatcher().handle(request);
            }
        });

Another route matcher:

public class SecureRoutes {
private static final RouteMatcher routeMatcher = new RouteMatcher();
@Inject
protected Container container;
@Inject
private SigninController signinController;
@Inject
private SignupController signupController;
@Inject
private OauthController oauthController;
@Inject
ClientNetworkSignalController clientNetworkSignalController;

public void initRoutes() {
    // APP routes. they use User token for authentication


    routeMatcher.get("/", new Handler<HttpServerRequest>() {
        @Override
        public void handle(final HttpServerRequest request) {
            request.response().putHeader("Cache-Control",
                    "public, max-age=86400");
            request.response().sendFile("web/public/index.html");
        }
    });


    routeMatcher.post("/signin", signinController.signin());
    routeMatcher.post("/signup", signupController.signup());
    routeMatcher.post("/oauth2/token", oauthController.token());
    routeMatcher.post("/oauth2/invalidate_token", oauthController.invalidateToken());

}

public RouteMatcher getRouteMatcher() {
    return routeMatcher;
}

}

Now finally add requestHandler to server:

server.requestHandler(routeMatcher).listen(port,
                host, new Handler<AsyncResult<HttpServer>>() {
                    public void handle(AsyncResult<HttpServer> asyncResult) {
                        if (asyncResult.succeeded()) {
                            logger.info(s + ":  Started on " + host + ":"
                                    + port);
                        } else {
                            logger.info(s + ": Unable to start server.\n "
                                    + asyncResult.cause());
                        }
                    }
                });

You may have a question What is the use of http options type request handler. The answer is for that is very interesting. Javascript is a secured language that do not allow Cross origin Http request. So, to allow cross origin request javascript send a options type request for each http request request and check weather CORS is supported or not. In such Javascript hits server two times one to check cors is supported or not and one to fatch data.