12

我不确定问题是所涉及的技术,还是我对这些技术的理解。

我有一个用 javascript 和 html 编写的 html5 应用程序,托管在 apache 2.2 服务器上。

我有一个用 java 编写的 java 应用程序,使用 jetty、guice、jackson、jersey 托管一个简单的 REST 服务。

两个应用程序在同一个机器上运行,一个在端口 80(托管在 apache 上的纯 html5 应用程序),另一个在 8080(托管在 jetty/guice 上的纯 java 应用程序)

我相信答案就在我发回的标题中。CORS 标头告诉浏览器您允许外部应用程序访问您的 api。我似乎无法弄清楚如何配置我的 Jetty、Guice 服务器以返回正确的 CORS 标头。

我使用的是嵌入式 Jetty 服务器,所以我没有 web.xml 文件来添加标题。

这也可能与 HTML5 应用程序服务器(在本例中为 apache 2.2)如何为应用程序提供服务有关。

apache httpd.conf 文件具有以下条目:

LoadModule headers_module modules/mod_headers.so

<IFModule mod_headers>
    Header add Access-Control-Allow-Origin "*"
    Header add Access-Control-Allow-Methods: POST, GET, OPTIONS, PUT, DELETE, HEAD
    Header add Access-Control-Allow-Headers: X-PINGOTHER
    Header add Access-Control-Max-Age: 1728000  
</IfModule>

在我的 guice servlet 配置中,我有以下内容:

public class RestModule extends ServletModule{

    @Override
    protected void configureServlets() {
        bind(QuestbookService.class);

        // hook Jersey into Guice Servlet
        bind(GuiceContainer.class);

        // hook Jackson into Jersey as the POJO <-> JSON mapper
        bind(JacksonJsonProvider.class).in(Scopes.SINGLETON);

        Map<String, String> guiceContainerConfig = new HashMap<String, String>();
        guiceContainerConfig.put(ResourceConfig.PROPERTY_RESOURCE_FILTER_FACTORIES,
            HttpStatusCodeMetricResourceFilterFactory.class.getCanonicalName());
        serve("/*").with(GuiceContainer.class, guiceContainerConfig);
    }
}

我认为问题出在我的 guice 配置中,因为我没有地方设置响应标头。

我正在使用嵌入式码头服务器,因此我认为开发模式会绕过整个检查,但我可能是错的。

谢谢你的任何建议。

4

3 回答 3

18

做我的应用程序的具体要求。服务器需要与客户端完全分开。客户端应该能够通过任何方法连接到通信服务器。

由于此应用程序的第一个实现将是 REST 驱动的,因此我需要能够从任何地方接受休息。

此外,我想要一个完全没有 xml 的配置,所以我使用带有嵌入式 Jetty 服务器的 Guice。由于我没有 web.xml 文件,我无法弄清楚如何设置标题以允许 CORS。

经过大量的试验和错误,并阅读了 guice 文档,我发现了如何将 CORS 标头添加到离开服务器的响应中。

Guice ServletModule 类允许您将过滤器添加到您的 servlet 上下文。这使我可以让所有请求都通过给定的 servlet。

由于我正在尝试构建一个响应 CORS 请求的 rest 应用程序,因此我需要一个过滤器,将 cors 标头添加到任何请求的响应中。

因此,为了使用 guice 在我的嵌入式服务器中启用 cors,我构建了一个如下所示的过滤器:

@Singleton
public class CorsFilter implements Filter{

    @Override
    public void doFilter(ServletRequest request, ServletResponse response,
    FilterChain filterChain) throws IOException, ServletException {

        if(response instanceof HttpServletResponse){
        HttpServletResponse alteredResponse = ((HttpServletResponse)response);
        addCorsHeader(alteredResponse);
    }

    filterChain.doFilter(request, response);
    }

    private void addCorsHeader(HttpServletResponse response){
        //TODO: externalize the Allow-Origin
        response.addHeader("Access-Control-Allow-Origin", "*");
        response.addHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, PUT, DELETE, HEAD");
        response.addHeader("Access-Control-Allow-Headers", "X-PINGOTHER, Origin, X-Requested-With, Content-Type, Accept");
        response.addHeader("Access-Control-Max-Age", "1728000");
    }

    @Override
    public void destroy() {}

    @Override
    public void init(FilterConfig filterConfig)throws ServletException{}
}

Guice 提供了一个抽象类,允许您配置 Guice Servlet。

配置模块如下所示:

public class RestModule extends ServletModule{

    @Override
    protected void configureServlets() {
        bind(MyServiceClass.class);

        // hook Jersey into Guice Servlet
        bind(GuiceContainer.class);

        // hook Jackson into Jersey as the POJO <-> JSON mapper
        bind(JacksonJsonProvider.class).in(Scopes.SINGLETON);

        Map<String, String> guiceContainerConfig = new HashMap<String, String>();

        serve("/*").with(GuiceContainer.class, guiceContainerConfig);

        filter("/*").through(CorsFilter.class);
    }
}

现在 guice 将为每个响应添加 cors 标头。允许我的纯 HTML 5 应用程序与它对话,无论它在哪里提供服务。

于 2013-05-05T01:16:21.903 回答
6

只需在代码文件中添加一行

response.addHeader("Access-Control-Allow-Origin", "*");

如果您只想允许特定域,请将 * 替换为您的http://www.yoursite.com

于 2014-07-24T07:13:52.870 回答
0

将此添加到您httpServletResponse的 java 端,即服务器端代码将解决该问题。

 httpServletResponse.addHeader("Access-Control-Allow-Origin", "*");
 httpServletResponse.addHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, PUT, DELETE, HEAD");
 httpServletResponse.addHeader("Access-Control-Allow-Headers", "X-PINGOTHER, Origin, X-Requested-With, Content-Type, Accept");
 httpServletResponse.addHeader("Access-Control-Max-Age", "1728000");
于 2019-07-27T09:20:42.570 回答