web-dev-qa-db-ja.com

OriginはAccess-Control-Allow-Originでは許可されていません-非常に単純なWebスタックとGuiceを使用してCORSを有効にする方法

問題が関連するテクノロジーなのか、テクノロジーに対する私の理解なのかはわかりません。

JavaScriptで記述されたhtml5アプリケーションと、Apache 2.2サーバーでホストされているhtmlを持っています。

簡単なJavaサービスをホストするjetty、guice、jackson、jerseyを使用してJavaで記述されたRESTアプリケーションが.

両方のアプリケーションは同じボックスで実行されます。1つはポート80(Apacheでホストされる純粋なhtml5アプリケーション)、もう1つは8080(純粋Java jetty/guiceでホストされるアプリケーション)

答えはヘッダーの返信にあると思います。 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サーブレット構成には、次のものがあります。

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設定にあると思います。

私は組み込みの突堤サーバーを使用しているため、開発モードがチェック全体をバイパスすると考えていましたが、間違っている可能性があります。

アドバイスありがとうございます。

11
AnthonyJClink

アプリケーションの特定の要件を実行します。サーバーはクライアントから完全に分離する必要があります。クライアントは、可能な方法で通信サーバーに接続できる必要があります。

このアプリケーションの最初の実装はREST=駆動されるため、どこからでも休憩を受け入れることができる必要があります。

さらに、完全にxmlのない構成が必要なので、組み込みのJettyサーバーでGuiceを使用します。 web.xmlファイルがないため、CORSを許可するようにヘッダーを設定する方法を理解できませんでした。

試行錯誤を繰り返し、guiceのドキュメントを読んだ後、サーバーを離れる応答にCORSヘッダーを追加する方法を見つけました。

GuiceのServletModuleクラスを使用すると、サーブレットコンテキストにフィルタを追加できます。これにより、すべてのリクエストが特定のサーブレットを通過できるようになります。

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サーブレットを構成できる抽象クラスを提供します。

構成モジュールは次のようになります。

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アプリケーションがそれと通信できるようにします。

14
AnthonyJClink

コードファイルに1行入力するだけです

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

特定のドメインのみを許可する場合は、*を http://www.yoursite.com に置き換えます。

6
kunal saxena

これを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");
0
bosari