티스토리 뷰

서로 다른 사이트 또는 같은 사이트의 HTTPS 프로토콜 호출인 Ajax 통신을 이용해서 JSON 구조의 데이터를 주고 받을일이 생길수 있습니다.

그럴경우 크롬,파이어폭스 같은 브라우저에서 아래와 같은 메세지를 만나게 될수 있습니다.

... No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin  ...

이유와 해결방법에 대해서 설명 해보겠습니다.


1.SOP (Same Origin Policy)

사실 위에 브라우저에서 보여주는 오류는 SOP 에 의한것이고 이것은 W3C 의 Client Side 보안정책중에 하나 입니다. 내용은 같은 스키마, 호스트, 포트가 일치할 경우에 문서나 스크립트에 접근할 수 있는 정책입니다. 
아래는 접근불가능의 예입니다.

https://www.xxx.com

http://www.xxx.com 

 프로토콜이 다름 

http://www.xxx.com:51

http://www.xxx.com:77 

 포트가 다름

http://test.xxx.com

http://dev.xxx.com 

 호스트가 다름


2.CORS(Cross Origin Resource Sharing)

서로 다른 도메인간 JSON의 접근은 예전부터 JSONP 라는 비표준적인 방법으로 가능 했었습니다.
하지만 요즘은 매시업 서비스가 많고 필수적이기 때문에 W3C 에서 CORS 이라는 표준적인 방법을 제시하고 있습니다.HTTP 응답 헤더 정보에 클라이언트가 접근가능에 대한 정보를 담아서 보내면 됩니다.
사실 위에서 본 오류 메세지의 Access-Control-Allow-Origin  값이 사용되는 헤더의 키 값이 됩니다.


3.테스트

아래는 간단한 테스트 입니다.

한개의 기본 웹어플리케이션을 생성 하고 HTTP port 를 8080 과  8081(JMX port 도 서로 다르게 해야 됩니다.)  각 2개의 서버를 구동하겠습니다. (생성 하는법은 생략)

context root 경로에 아래 2개의 jsp 파일을 위치 시켜놓습니다. 


1.my-server.jsp :파일은 전송 버튼을 클릭하면 ajax 로 json 데이터를 요청 하는 기능이 있는 화면입니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
<%@ page contentType="text/html;charset=UTF-8"%>
<html>
  <head>
    <title></title>
    <script
            src="https://code.jquery.com/jquery-3.2.1.min.js"
            integrity="sha256-hwg4gsxgFZhOsEEamdOYGBf13FyQuiTwlAQgxVSNgt4="
            crossorigin="anonymous"></script>
    <script type="application/javascript">
        function testCall() {
            $.ajax({
                dataType:'json',
                url: "http://localhost:8081/your-server.jsp",
                data: {},
            }).done(function (data) {
                console.log(data);
            })
        };
    </script>
  </head>
  <body>
  <input type="button" onclick="testCall()" value="전송"/>
  </body>
</html>
 
cs


2.your-server.jsp: 단순한 json 구조의 데이터를 응답하는 화면 입니다. 

1
2
3
4
5
6
<%@ page contentType="application/json;charset=UTF-8"  language="java" %>
<%
//response.setHeader("Access-Control-Allow-Origin","*");
%>
{"name":"무명소졸"}
 
cs


크롬브라우저에서 http://localhost:8080/my-server.jsp 를 호출한 후에 전송 버튼을 클릭 해봅니다. 

크롬관리자도구의 console 탭에서 아래와 같은 오류 메세지가 발생하는것을 확인 할수 있습니다.

Failed to load http://localhost:8081/your-server.jsp: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:8080' is therefore not allowed access.




Port가 8081 인 곳의 요청에 대한 응답을 받았기 때문에 SOP 정책에 의해서 발생한 것입니다.
  $.ajax({
                dataType:'json',
                url: "http://localhost:8081/your-server.jsp",
                data: {},
            })


번에는 your-server.jsp 에 아래의 주석을 제거하고 다시 시도해봅니다.

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

이번에는 정상적으로 처리되는것을 확인할수 있습니다. "*" 이 옵션은 전체 허용을 뜻합니다.

하지만 좀더 많고 정교한 옵션들이 존재 합니다. 아래 사이트에서 좀더 자세한 내용은 확인 하실수 있습니다.


https://developer.mozilla.org/ko/docs/Web/HTTP/Access_control_CORS


공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크