Access-Control-Allow-Origin不允许使用Origin - 如何使用非常简单的Web堆栈和guice启用CORS

Ant*_*ink 11 java apache html5 guice cross-domain

我不确定问题是涉及的技术,还是我对技术的理解.

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

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

两个应用程序都运行在同一个盒子上,一个在端口80上(纯粹的html5应用程序托管在apache上),另一个在8080上(在jetty/guice上托管的纯Java应用程序)

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

我正在使用一个imbeded 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>
Run Code Online (Sandbox Code Playgroud)

在我的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);
    }
}
Run Code Online (Sandbox Code Playgroud)

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

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

谢谢你的任何建议.

Ant*_*ink 14

满足我的应用程序的特定要求.服务器需要从客户端完全分离.客户端应该能够通过任何方法连接到通信服务器.

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

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

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

Guice ServletModule类允许您向servlet上下文添加过滤器.这允许我让所有请求都通过给定的servlet.

由于我正在尝试构建响应CORS请求的休息应用程序,因此我需要一个过滤器,它将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{}
}
Run Code Online (Sandbox Code Playgroud)

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);
    }
}
Run Code Online (Sandbox Code Playgroud)

现在,guice将为每个响应添加cors标头.允许我的纯HTML 5应用程序与它通信,无论它在何处提供.


kun*_*ena 6

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

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

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