일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 | 26 | 27 | 28 |
29 | 30 | 31 |
- 소프티어
- 정보처리산업기사
- 코딩교육봉사
- SW봉사
- 코틀린
- SQL
- 스프링
- 자바
- 파이썬
- 데이터베이스
- CJ UNIT
- 알고리즘
- MYSQL
- 코딩봉사
- java
- 공부일지
- 프로그래머스
- 회고
- 백준 알고리즘
- kotlin
- 문제풀이
- 1과목
- 백준알고리즘
- softeer
- 백준
- programmers
- BFS
- python
- 시나공
- C++
- Today
- Total
JIE0025
[개발/JS] 다른 모듈의 팝업을 호출하여 발생한 Cross-Origin 문제 해결과정 - postMessage() 본문
[개발/JS] 다른 모듈의 팝업을 호출하여 발생한 Cross-Origin 문제 해결과정 - postMessage()
Kangjieun11 2024. 12. 3. 00:07
✅ 문제상황
A모듈의 메뉴에서 C모듈의 팝업을 호출한다.
C모듈 팝업에서 버튼한개를 클릭하면 공통쪽 팝업이 뜨는데...
여기에서 공통 팝업이 제대로 뜨지 않는 문제가 발생했다.
✅ 해결 과정
코드 확인 결과, 공통 팝업을 띄우기 위해선
1. 메뉴인경우 해당 페이지의 정보를 저장한다.
--> A모듈 메뉴1 에서 공통팝업 호출시 A의 정보저장
2. 해당 페이지 정보가 없는 경우 (ex 팝업) 그 부모의 정보를 가져와서 저장한다.
--> A모듈에 메뉴1에서 A모듈 팝업1을 호출한 다음 공통팝업 호출시 팝업1의 부모인 메뉴1의 정보 저장
문제가 생겼던 부분은
이 경우는 A에서 C팝업을 호출했기 떄문에 부모의 정보를 제대로 가져오지 못하여 발생하는 것이었다.
크로스오리진을 해결하기 위해선 postMessage를 이용하여 값을 전달하는 방법이 있다.
✅ postMessage()
다른 도메인간 메세지 송수신이 가능한 API
같은 오리진 정책때문에 기본적으로는 서로 다른 도메인에서 데이터를 주고 받을 수 없다.
postMessage()는 이를 안전하게 우회할 수 있게 도와준다.
예를들어 페이지 - 팝업, 페이지 - iframe 등 서로 다른 윈도우 객체간 데이터를 주고받는데에도 사용될 수 있다.
postMessage(message, targetOrigin, transfer);
message : 전송할 데이터
targetOrigin : 메세지 받을 도메인
transfer : (선택) 객체 전송시 소유권 전달
Example
"https://example.com"라는 도메인으로
"Hello"라는 문자열 객체를 전송한다고 가정하자.
popup.postMessage("Hello!", "https://example.com");
message 수신
window.addEventListener("message", (event) => {
// 나한테 보낸 메시지가 신뢰할 수 있는 출처에서 온 것인지 확인하기 위함
if (event.origin !== "https://example.com") return;
console.log(event.data); // 전송받은 데이터
});
포스트메세지는 출처가 다른 여러곳에서 자유롭게 메세지를 주고받는 기능인데
이게 보안 위험으로 넘어갈 수 있기 떄문에
나한테 보낸 메세지인지 확인하기 위한 코드가 추가된다.
메인페이지에서 팝업창 열때 데이터를 보내준다.
const popup = window.open("https://example.com/popup");
parent = {};
parent.infoA = "aa";
parent.infoB = "bb";
popup.postMessage({ param: parent }, "https://example.com");
// 팝업에서 데이터 수신
window.addEventListener("message", (event) => {
if (event.origin !== "https://example.com") return; // 보안 체크
console.log(event.data);
});
이런식으로 필요한 데이터를 넘기면 되는데...
내 경우엔 팝업 호출하는 내부 코드에 postMessage가 이미 존재했다.
(이미 팝업창을 띄우는 과정에서 postMessage를 사용하고 있었다)
그래서 A-메뉴에서 버튼클릭하는 순간 (팝업 호출하는쪽)
해당 메뉴의 정보를 param으로 넘겨주는것만으로도 해결할 수 있었다.
var parent = {}
parent.menuInfoA = aa
parent.menuInfoB = bb
parent.menuInfoC = cc
functionPopupOpen( {type :"VIEW", param: { otherValue: otherValue , parent: parent }} );
최종적으로 가져온 값을 갖고 팝업 오픈전 설정시 사용하니
정상 작동 확인할 수 있었다!
References
https://developer.mozilla.org/en-US/docs/Web/API/Window/postMessage
https://m.blog.naver.com/hyoun1202/221932249560
'백엔드 > 이슈, 트러블슈팅' 카테고리의 다른 글
[쿼리 튜닝] 시스템 응답 속도 개선 과정 (0) | 2024.12.02 |
---|---|
[리팩토링] Mapper 캐시 설정 변경으로 데이터 무결성 지키기 (MyBatis - useCache, flushCache) (0) | 2024.04.29 |
한 트랜잭션에서 동일한 데이터를 조회하면? (MyBatis의 캐싱전략과 localCacheScope 설정하기) (0) | 2024.04.16 |
[AWS] EC2 프리티어 메모리 부족으로 발생한 빌드 실패와 해결과정 (0) | 2023.06.24 |
보이어무어로 한글을 매칭하면 성능이 안좋다 ? (효율적으로 문자열 매칭하기) (0) | 2023.06.13 |