「No 'Access-Control-Allow-Origin' header is present on the requested resource. 」というエラーに遭遇しました

  • 2
    いいね
  • 0
    コメント
この記事は最終更新日から1年以上が経過しています。

初めてのSpring Boot」でREST Webサービスを写経し、Dartでクライアントサイドを記述してみたのですが、お手本どおりのコードではDartEditorにて下記のエラーになりました。

DartEditorで表示されたエラー
XMLHttpRequest cannot load http://localhost:8080/api/customers. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:8081' is therefore not allowed access.
Exception: Uncaught Error: Instance of '_XMLHttpRequestProgressEvent'

環境

  • Windows 7 (64bit)
  • DartEditor 1.9.3
  • Spring Boot 1.1.11.RELEASE

対策

JavaScript プログラミング講座」によると、クロスオリジンリソースシェアリング(CORS)というHTML5世代の仕様らしく、任意の Web ページから、別のリソース格納場所にあるリソースを読み取りアクセスする事は、基本できないそうです。

ただこれを回避する方法はあって、サーバ側にてアクセスコントロール情報を付加したレスポンスを返せば良いんだそうです。

Springのサイトにちょうど?それに関する説明があって、レスポンス内にCORSを追加させる方法が載っていました。

正直本質的な意味は理解できていませんが、このサイトにある以下のコードを追加すれば問題は解決しました。

CORSに対応させるコード
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletResponse;
import org.springframework.stereotype.Component;

@Component
public class SimpleCORSFilter implements Filter {

    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
        HttpServletResponse response = (HttpServletResponse) res;
        response.setHeader("Access-Control-Allow-Origin", "*");
        response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE");
        response.setHeader("Access-Control-Max-Age", "3600");
        response.setHeader("Access-Control-Allow-Headers", "x-requested-with");
        chain.doFilter(req, res);
    }

    public void init(FilterConfig filterConfig) {}

    public void destroy() {}

}

参考