OPTIONS返回200

时间:2015-08-12 01:51:56

标签: java jquery ajax cors embedded-jetty

我有一个嵌入式Jetty v9.2.10服务器,其中设置了跨源过滤器(org.eclipse.jetty.servlets.CrossOriginFilter)。服务器上有一个REST服务,我正在尝试使用jQuery POST。 POST尝试获取Firefox中的OPTIONS请求;交流如下:

请求标题

Host: localhost:8402
User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:39.0) Gecko/20100101 Firefox/39.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Origin: http://localhost
Access-Control-Request-Method: POST
Access-Control-Request-Headers: content-type
Connection: keep-alive
Pragma: no-cache
Cache-Control: no-cache

回复标题

Allow: HEAD, POST, GET, OPTIONS
Content-Length: 24
Content-Type: text/plain
Date: Wed, 12 Aug 2015 00:57:35 GMT
Expires: Thu, 01 Jan 1970 00:00:00 GMT
Server: Jetty(9.2.10.v20150310)

(值得注意的是,我不希望在响应中出现任何Access-Control标头。)如果我在Chrome中尝试它,它的网络调试器告诉我对OPTIONS请求的响应是不安全的,所以我甚至看不到回来的东西,但这可能是一个单独的问题。

以下是发出请求的JavaScript:

    $(document).ready(function(){
        var queryString = URI.parseQuery(URI(window.location.href).search()); 
        var cred = "/*a really long token*/";
        $.ajax({
                type: "POST",
                url: "https://localhost:8402/api/v1/resource/agent/" + queryString.agentId + "/connector?token=" + cred,
                data: {
                    //some JSON
                },
                success: function(data,status){
                    alert("Response: " + data + "\nStatus: " + status);
                },
                crossDomain: true,
                contentType: 'application/json'
        });
    });

以下是我在服务器上设置CORS过滤器的方法:

private void addCorsFilter(ServletContextHandler servletHandler)
{
    FilterHolder corsFilter = servletHandler.addFilter(CrossOriginFilter.class, "/*", EnumSet.allOf(DispatcherType.class));
    // this string is set to "http(s?)://localhost*" as I have everything running locally right now, but setting to "*" doesn't make a difference
    String studioDomain = environmentVariableReader.read(Constants.Env.STUDIO_DOMAIN);
    corsFilter.setInitParameter(CrossOriginFilter.ALLOWED_ORIGINS_PARAM, studioDomain);
    corsFilter.setInitParameter(CrossOriginFilter.ACCESS_CONTROL_ALLOW_ORIGIN_HEADER, "*");
    corsFilter.setInitParameter(CrossOriginFilter.ALLOWED_METHODS_PARAM, "GET,POST,HEAD,PUT,OPTIONS");
    corsFilter.setInitParameter(CrossOriginFilter.ALLOWED_HEADERS_PARAM, "X-Requested-With,Content-Type,Accept,Origin");
    corsFilter.setInitParameter(CrossOriginFilter.ACCESS_CONTROL_ALLOW_CREDENTIALS_HEADER, "true");
    logger.info("cross-origin filter allowing {}", studioDomain);
}

我尝试使用来自两个答案here的说明设置CrossOriginFilter - 以及通配许多字段 - 但大多数配置都给出了相同的结果。如果他们愿意,我可以提供相关的Jetty日志。

1 个答案:

答案 0 :(得分:1)

这个问题与此处的任何内容无关。过滤实际上是由Guice处理的,只有在它通过它知道的过滤器并尝试使用它注入的servlet服务请求之后才会委托给Jetty的过滤器链。我不知道这个,所以我没有将CrossOriginFilter添加到Guice的ServletModule。因此,Guice尝试使用它注入的RESTEasy调度程序servlet来服务请求(因此响应看起来像默认的HttpServlet.doOptions())并且不会使用Jetty的过滤器链,因为请求已被服务。