Access-Control-Allow-Origin 不允许 Origin - 如何使用非常简单的网络堆栈和 guice 启用 CORS [英] Origin is not allowed by Access-Control-Allow-Origin - how to enable CORS using a very simple web stack and guice

查看:29
本文介绍了Access-Control-Allow-Origin 不允许 Origin - 如何使用非常简单的网络堆栈和 guice 启用 CORS的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am not sure if the issue is the technologies involved, or my understanding of the technologies.

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

I have an html5 application written in javascript and html hosted on an apache 2.2 server.

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

I have a java application written in java using jetty, guice, jackson, jersey that hosts a simple REST service.

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

Both applications run on the same box, one on port 80 (pure html5 application hosted on apache), the other on 8080 (pure java application hosted on jetty/guice)

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

I believe the answer is in the headers im sending back. The CORS headers tell a browser that you allow outside applications to hit your api. I cannot seem to figure out how to configure my Jetty, Guice server to return the correct CORS headers.

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

I am using an imbeded Jetty server so I do not have a web.xml file to add the headers with.

这也可能与 HTML5 应用程序服务器(在本例中为 apache 2.2)为应用程序提供服务的方式有关.

It also might be something to do with how the HTML5 application server (in this case apache 2.2) is serving the application.

apache httpd.conf 文件有条目:

The apache httpd.conf file has the entry:

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 配置中,我有以下内容:

in my guice servlet configuration I have the following:

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 配置中,因为我没有地方设置响应头.

I think the problem is in my guice config since I don't have a place to set the response headers.

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

I am using an embedded jetty server and thus I figured dev mode would bypass the whole check, but I could be wrong.

感谢您的建议.

推荐答案

对我的应用程序的具体要求做.服务器需要与客户端完全分离.客户端应该能够通过它可以使用的任何方法连接到通信服务器.

Do to the specific requirements of my application. The server needs to be seporate completly seporate from the client. The client should be able to connect to the communication server via any method it can.

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

Since the first implementation of this application is going to be REST driven, I need to be able to accept rest from anywhere.

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

In addition, I want a completly xml-less config, so I use Guice with an imbedded Jetty server. Since I do not have a web.xml file, I could not figure out how to set the headers to allow CORS.

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

After alot of trial and error, and reading the guice documentation, I found how to add the CORS headers to the response leaving the server.

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

The Guice ServletModule class allows you to add filters to your servlet context. This allows me to have all requests pass through a given servlet.

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

Since I am trying to build a rest application that responds to CORS requests, i needed a filter that added the cors headers to the response of any request.

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

So to enable cors in my embedded server using guice I built a filter that looks like this:

@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.

Guice provides an abstract class that allows you to configure the 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 应用程序与它对话,无论它在何处提供.

Now guice will add cors headers to every response. Allowing my pure HTML 5 application to talk to it, no matter where it is being served.

这篇关于Access-Control-Allow-Origin 不允许 Origin - 如何使用非常简单的网络堆栈和 guice 启用 CORS的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆