@ 주제 

CORS (Cross-origin resource sharing)   사이트간  데이터 주고 받기

 

@ 목적 

URL 이 다른 사이트간 데이터 전송 작업을 위함 

 

@ 내용 

CORS (Cross-origin resource sharing) : 서로 다른 도메인에서 리소스를 공유하는 방식? 이라 볼 수 있다 . 

기존에 있는 Same-Origin Policy ( 동일 출처 정책)와 반대 되는 개념으로 보면된다. 

 

  • 자바스크립트가 할 수 없는 것들 참고하기 

 

 

예를 들어, www.example.com 이라는 사이트에서 사용하는 api가 있다. 해당 api는 외부에 공개하려는 목적이 아닌, 자신들의 사이트에서 사용하기 위해 만들었다고 치자. 그런데 이 api를 다른 사이트에서 알게 되었고 허락없이 무단으로 가져다 사용하게 된다면 이 사이트 입장에서는 상당히 곤란할 것이다. 그래서 나온 것이 Same-origin policy 정책이다. 프로토컬, 도메인, 포트가 모두 같을시 동일 출처 정책을 따른다고 볼 수 있다. 

 

보통 api를 사용할 때, ajax를 사용하는데 이 same-origin policy를 따르지 않을 경우, 오류가 나면서 api 사용이 거절된다. 

 

이걸 해결할 수 있는 방법 중 하나는 JSONP 방식이 있다. 

 js, css 등의 파일은 same-origin policy를 따르지 않아도 되기 때문에 서버에서 값을 돌려줄때 마치 js 파일처럼 값을 돌려주고, 클라이언트에서는 이 값을 콜백 함수로 재처리 하여 사용하는 방식이다.

 

JSONP 방식은 서버단에서 리턴해 줄 때 콜백함수이름으로 감싸서 보내주어야 한다.

예) CALLBACK NAME : myCall인 경우 myCall([{name:"철수"}])  

 

 

스프링에서도 이를 해결할 수 있는 방법이 있는데 

샘플 시작~~ 

 

-- jsp 

var json2 = {myCode: 1212056, rvFlag: 1, vnr:"A0001"};

                

                $.ajax({

                      url: "http://10.10.10.10:8518/api/if/test_aaa",

                      data: JSON.stringify(json),

                      type: "POST",          

                      beforeSend: function(xhr) {

                          xhr.setRequestHeader("Accept", "application/json");

                          xhr.setRequestHeader("Content-Type", "application/json");

                      },

                      success: function(data){

                          console.log(data);

                      }

                });



-- Controller 









// @CrossOrigin(origins = "http://domain1.com, http://domain2.com") 이런식으로 허용하고 싶은 도메인만 설정도 가능하다. 

@CrossOrigin //  @CrossOrigin 어노테이션을 붙여주면 기본적으로 '모든 도메인, 모든 요청방식' 에 대해 허용 한다는 뜻이다.

@Controller

@RequestMapping("/api/if")

public class InterfaceResource {

    

    @Autowired HttpServletRequest request;

    @Autowired HttpServletResponse response;

    @Autowired InterfaceService interfaceService;

    

    

    



    @ResponseBody

    @CrossOrigin

    @RequestMapping(method = {RequestMethod.GET, RequestMethod.POST },  headers = "Accept=application/json", value="/status")

    public ResponseEntity<?> a_status(@RequestBody Test test){

        

        Map<String, Object> res = new HashMap<>();

        res.put("RESPONSE", interfaceService.a_status(test));    

        return new ResponseEntity<>(res, HttpStatus.OK);

    }

    

    



    

    @ResponseBody

    @CrossOrigin

    @RequestMapping(method = { RequestMethod.GET, RequestMethod.POST }, headers = "Accept=application/json", value="/aprv")

    public ResponseEntity<?> apon_pms_aprv(@RequestBody Test test){

        Map<String, Object> res = new HashMap<>();

    

        res.put("RESPONSE", interfaceService.aprv(test));

        return new ResponseEntity<>(res, HttpStatus.OK);

    }

    



    //해더에 넣을거면

    /*HttpHeaders headers = new HttpHeaders();

    headers.set("Content-type", "application/javascript;charset=UTF-8");

    headers.add("RTN_TYPE", res.get("RTN_TYPE"));   

    headers.add("RTN_MSG", res.get("RTN_MSG"));*/  



}

--- service 

public Map<String, Map<String, String>> b_status(Test test) {

        Map<String, Map<String, String>> response = new HashMap<String, Map<String, String>>();

        Map<String, String> output = new HashMap<String, String>();

        Map<String, String> header = new HashMap<String, String>();

        

        System.out.println(test.getMyCode());



        String projectNo = test.getMyCode();

        if( StringUtils.isEmpty(projectNo) ) {

            this.setMyHeader("E", "MYCODE IS EMPTY", header);

            response.put("HEADER", header);

            return response;

        }

        

        // GET PMS INFOMATION

        Project p = projectRepository.getProjectByProjectNo(projectNo);

        if(p.getProjectId() != null ) {

            

            output.put("NAME", p.getProjectTitle());  

            output.put("CREATOR", p.getCreatedBy() != null ? p.getCreatedBy().getName() : "-");    

            output.put("STATUS", p.getAponStatus() != null ? String.valueOf(p.getAponStatus()) : "");

            this.setMyHeader("S", "OK", header);

            

        } else {

            this.setMyHeader("E", "COULD NOT FIND MATCHING PROJECT", header);

            response.put("HEADER", header);

            return response;

        }

        

        

        response.put("HEADER", header);

        response.put("OUTPUT", output);

        

        return response;

    }





-- VO 

package kr.co.bpnr.amorepms.service.dto;



import lombok.Data;

@Data   // 롬복에서는 @Data 어노테이션을 적어주면 getter setter 전부 처리해주기 때문에 새로 만들 필요가 없다. 

public class TEST {

    //*  MYCODE    : project_no

    //*  APRVFLAG: 결재상태

    //*  APVNR    : 결재문서 Doc ID

    

    private String myCode;        

    private String rvFlag;        

    private String pvnr;



    

}

 

 

 

'기능 정리' 카테고리의 다른 글

오라클 시간별 조회방법 조건절 !  (0) 2021.02.25
Git ignore white space 설정  (0) 2021.01.14
자바스크립트가 할 수 없는 것들  (0) 2020.08.13
Same-Origin Policy  (0) 2020.08.12
util 태그 라이브러리의 사용  (0) 2020.08.11

@ 주제 

Same-Origin Policy 이란 무엇인가 

 

@ 목적 

CORS 작업을 진행하며 알게된 내용 정리 

 

@ 내용 

Same-Origin Policy 

동일 출처 정책(same-origin policy)은 자바스크립트 코드가 웹 콘텐츠와 상호 작용을 할 수 있다는 사실 전반에 걸친 폭넓은 보안 제약 사항이다. 이 정책은 일반적으로 <iframe>요소를 포함한 웹 페이지나 새로운 브라우저 창이 열릴 때 작동하는데, 한 창이나 프레임의 코드는 동일 출처 정책의 감독하에 다른 창이나 프레임과 상호작용한다. 다시 말해서 자바스크립트는 스크립트를 포함하고 있는 문서와 같은 출처의 문서에 있는 window와 Document 객체의 속성만을 사용할 수 있다. 

 

문서의 출처는 불러온 URL의 프로토콜과 호스트, 포트로 정의한다. 다른 여러 서버에서 불러온 문서는 출처가 다르다.  같은 호스트에 포트만 다른 서버에서 불러온 문서도 출처는 다르다. 또한 http: 프로토콜을 사용해서 불러온 문서는 https:프로토콜을 사용해서 불러온 문서와 출처가 다르다.

 

그러나 스크립트 파일의 출처는 동일 출처 정책과 전혀 관계가 없다. 중요한 것은 스크립트를 포함하고 있는 문서의 출처다.

 

 

* 에러발생 

html 파일에서 ajax로 

통신이 이루어지는지 잘 보이기 위한 테스트 페이지를 구현하기 위해

url이 다른 서버로 요청을 보냈다. 

 

Access to XMLHttpRequest at 'file:///D:/apache/index.html' from origin 'null' has been blocked by CORS policy: Cross origin requests are only supported for protocol schemes: http, data, chrome, chrome-extension, brave, https.

 

* 원인

같은 경로의 자원을 요청하는데 에러 메세지엔 보시다시피 origin, 즉 출처가 null 로 넘어온 script에 대한 접근이 CORS 정책에 따라 제한되었다고 나와있습니다. 

 

D:/apache/index.htm 에서 ajax로 c:/경로/js/test.js에 리소스를 요청한 건 동일 경로의 리소스를 요청한 것이 아니고
D:/apache/index.htm 에서 null/js/test.js로 리소스를 요청한 것이 되어 CORS에러가 발생한 것입니다.

 

 

 

웹 서버에 올려 프로토콜 호스트 포트를 같게 만들면 CORS 에러가 해결되는데,

 

같게 할 수 없는 상황에선 특정 플러그인을 사용하거나 jsonp 방식을 사용한다. 

 

+ Recent posts