μ€λμ λ³λ 컨ν μ€νΈλ₯Ό κ°μ§ μ μ°½μ λμ°λ κ°λ°μ νλ©° μκ²λ λ΄μ©μ μ 리ν΄λ³΄λ € ν©λλ€.
μ μμ§λ window.openμ΄ νμνκ°?
μμμ μ νμ κ³Ό λͺ¨λ¬μ λ³Έμ§μ μ°¨μ΄λΆν° μμλ³΄κ² μ΅λλ€.
νμ μ°½
- λΈλΌμ°μ κ° μμ ν λΆλ¦¬λ μ μ°½(λλ ν)μΌλ‘ λμ
- λΈλΌμ°μ μ νμ μ°¨λ¨ κΈ°λ₯μ μν₯μ λ°κ³
- λΆλͺ¨ νμ΄μ§μ λ³λμ λΈλΌμ°μ 컨ν μ€νΈλ₯Ό κ°μ΅λλ€.
- μ°½μ μμΉ, ν¬κΈ°, μ€ν¬λ‘€λ° λ± λ€μν μμ±μ μ μ΄ν μ μμ΅λλ€.
- λΆλͺ¨ μ°½μ΄ μλ‘κ³ μΉ¨λκ±°λ μ΄λν΄λ νμ μ μ μ§λ©λλ€.
- λΈλΌμ°μ νμ μ°¨λ¨ κΈ°λ₯μ μν΄ μ¬μ©μκ° νμ μ λͺ» λ³Ό μ μμΌλ―λ‘, λ°λμ νμν κ²½μ°μλ§ μ¬μ©νλκ² μ’μ΅λλ€. κ·Έ μΈμλ λͺ¨λ¬μ΄ κΆμ₯λ©λλ€.
λͺ¨λ¬μ°½
- κΈ°μ‘΄ νμ΄μ§ μμ μ€λ²λ μ΄ λ μ΄μ΄λ‘ ꡬν
- λΆλͺ¨ νμ΄μ§μ μ’ μλμ΄ μμ΅λλ€.
- λΈλΌμ°μ μ νμ μ°¨λ¨ κΈ°λ₯κ³Ό 무κ΄ν©λλ€.
- λΆλͺ¨ νμ΄μ§κ° μ΄λ λλ μλ‘κ³ μΉ¨λλ©΄ λͺ¨λ¬λ μ¬λΌμ§λλ€.
- λ³λμ λΈλΌμ°μ 컨ν μ€νΈκ° μλλ―λ‘, μΈλΆ λλ©μΈ νμ΄μ§λ₯Ό μ§μ ν¬ν¨ν μ μμ΅λλ€. μ΄λ iframeμ μκ°νμ€ μ μλλ° λ³΄μμ μ μ½μ΄ λ§μ λΆνΈν©λλ€.
Reactμμλ μν(state)λ₯Ό νμ©ν μ‘°κ±΄λΆ λ λλ§μΌλ‘ νμ μ ꡬννκ±°λ, Tossμ μ€λ²λ μ΄ ν€νΈ(Overlay Kit)κ°μ λΌμ΄λΈλ¬λ¦¬λ₯Ό μ¬μ©νλ κ²½μ°κ° λ§μ΅λλ€.
κ·Έλ°λ°λ μ¬μ ν window.open()μ΄ νΈλ¦¬νκ±°λ νμν μν©μ΄ μμ΅λλ€.
- μΈλΆ λλ©μΈκ³Όμ μ°λ: OAuth μΈμ¦, κ²°μ μμ€ν
μ°λ λ± λ€λ₯Έ λλ©μΈμ νμ΄μ§λ₯Ό μ΄μ΄μΌ ν λ
- OAuth μΈμ¦μ΄λ μΈλΆ κ²°μ μμ€ν μ°λ μ, 보μμ΄λ μ¬μ©μ μΈμ¦ ν μ½λ°±λ±μ UX μ μΈ μ΄μ λ‘ λ³λ μ°½μ΄ νμν©λλ€.
- μ΄λ window.open()μ μ¬μ©νλ©΄ λΆλͺ¨-μμ μ°½ κ° ν΅μ μ΄λ μ°½ λ«ν κ°μ§ λ±μ μ²λ¦¬κ° μ¬μμ Έμ.
- λͺ¨λ¬λ‘λ μΈλΆ λλ©μΈ νμ΄μ§λ₯Ό iframeμΌλ‘ λμ°λ κ²μ΄ CORS, X-Frame-Options λλ Content-Security-Policy λ±μ 보μ μ μ± λ±μ μ΄μ λ‘ λΆνΈν©λλ€.
- νλ¦°νΈ κΈ°λ₯: νΉμ μ½ν
μΈ λ§ νλ¦°νΈνκΈ° μν λ³λ μ°½μ΄ νμν λ
- μ μ°½μ ν΄λΉ μ½ν μΈ λ§ λ λλ§νκ³ window.print()λ₯Ό νΈμΆνλ λ°©μμ΄ λ§μ΄ μ¬μ©λμ΅λλ€.
- λͺ¨λ¬μ΄λ μ€λ²λ μ΄λ‘λ μ 체 νμ΄μ§μ μΌλΆλ§ κΉλνκ² μΈμνλ μΈμ λ²μ μ μ΄κ° μ΄λ €μ κΈ°μ‘΄ νμ΄μ§ μ μ²΄κ° μΈμλ©λλ€.
- λ°λΌμ μ μ°½μ΄ κ°μ₯ κ°λ¨νκ³ νμ€ν λ°©λ²μ΄λΌ μκ°ν©λλ€.
- λ©ν°νμ€νΉ UX: μ¬μ©μκ° λ νλ©΄μ λμμ 보며 μμ
ν΄μΌ ν λ
- λ κ°μ μ°½μ λμμ νλ©΄μ λμ μνΈ λΉκ΅ μμ νλ €λ©΄ μ°½ λΆλ¦¬κ° νμν©λλ€.
- λͺ¨λ¬μ νμ λΆλͺ¨ μ°½ μμ λ μκΈ° λλ¬Έμ λ νλ©΄μ λμμ λ³Ό μ μμ΅λλ€.
- λ°λΌμ μ μ°½μ λμ°λ κ²μ΄ μ μΌν λ°©λ²μ λλ€.
- λ κ±°μ μμ€ν
ν΅ν©: κΈ°μ‘΄ μμ€ν
κ³Όμ νΈνμ±μ μν΄ νμν κ²½μ°
- κΈ°μ‘΄ μμ€ν μμ νμ μ°½μ ν΅ν λ°μ΄ν° κ΅νμ΄λ μΈμ¦ λ±μ κ΅¬μ‘°κ° μ΄λ―Έ window.open()μ λ§μΆ°μ Έ μλ€λ©΄, μ΄λ₯Ό λͺ¨λ¬λ‘ λ체νλ κ²½μ° νΈνμ± μ΄μκ° λ°μν μ μμ΅λλ€.
- λ³λ μλμ° κΈ°λ₯: λΆλͺ¨ μ°½μ μλ‘κ³ μΉ¨μ΄λ μ΄λμλ μ μ§λμ΄μΌ νλ λ
립μ κΈ°λ₯
- λͺ¨λ¬μ΄λ SPA μ»΄ν¬λνΈλ‘λ ꡬνμ΄ λΆκ°λ₯ν©λλ€.
- μλ‘μ΄ νμ μ°½λ§μ΄ μμ ν λ³λμ λΈλΌμ°μ 컨ν μ€νΈλ₯Ό μ 곡ν©λλ€.
μ΄λ° κ²½μ°μλ window.open()μ μ¬μ©ν΄μΌ νλλ°, μμ νκ³ μ¬λ°λ₯Έ λ°©λ²μ μμλ³΄κ² μ΅λλ€.
window.open('javascript:focus()', 'myPopup', 'width=800,height=600');
κ²λ³΄κΈ°μ μ μλν μ μμ§λ§, μ΄ λ°©μμ 보μμ λ¬Έμ κ° μμΌλ©° 곡μμ μΌλ‘ κΆμ₯λμ§ μλ λ°©μμ λλ€.
μ΄λ² κΈμμ κ·Έ μ΄μ μ λν΄ μ μ΄λ³΄λ €ν©λλ€! λν μ΄λ€ λ°©μμ΄ μμ νκ³ νμ€μ λΆν©νλμ§λ μμλ³΄κ² μ΅λλ€.
javascript:focus() λ°©μμ μνμ±
μ΄ λ°©μμ javascript: URL μ€ν΄μ μ΄μ©ν΄ μ μ°½μ μ΄λ©΄μ focus() ν¨μλ₯Ό μ€ννλ €λ μλμ λλ€. νμ§λ§ μ΄λ° λ°©μμ 보μμ μ·¨μ½ν©λλ€.
MDN 곡μ λ¬Έμμμλ λ€μκ³Ό κ°μ΄ λͺ νν κ²½κ³ νκ³ μμ΅λλ€.
"Use of javascript: URLs on the web is discouraged as it may lead to execution of arbitrary code, similar to the ramifications of using eval()."
λν, ESLintμμλ no-script-url κ·μΉμ ν΅ν΄ javascript: URL μ€ν΄ μ¬μ©μ κΈμ§νκ±°λ κ²½κ³ νκ³ μμ΅λλ€. μ΄λ μ½λκ° μΈλΆ μ λ ₯μ μν΄ μ‘°μλκ±°λ μ μ©λ μ μκΈ° λλ¬Έμ λλ€.
μμ½νμλ©΄
- 보μμ μν (μμ μ½λ μ€ν κ°λ₯μ±)
- XSS(ν¬λ‘μ€ μ¬μ΄νΈ μ€ν¬λ¦½ν ) 곡격μ 벑ν°κ° λ μ μμ
- μ΅μ λΈλΌμ°μ λ° λ¦°ν° μ°¨λ¨ λμ
- μ μ§λ³΄μμ μλ νμ μ΄ μ΄λ €μ
νμ€μ μ΄κ³ μμ ν λ°©λ²: about:blank λλ λΉ λ¬Έμμ΄
νμ μ μμ νκ² μ΄κ³ μΆλ€λ©΄, κΆμ₯λλ λ°©μμ λ€μκ³Ό κ°μ΅λλ€.
const popup = window.open('about:blank', 'myPopup', 'width=800,height=600');
if (popup) {
popup.location.href = '/your-target-page';
popup.focus(); // νμ μ ν¬μ»€μ€ μ΄λ
}
λλ μμ λΉ λ¬Έμμ΄λ μ¬μ©ν μ μμ΅λλ€.
const popup = window.open('', 'myPopup', 'width=800,height=600');
μ΄ λ°©μμ λ€μκ³Ό κ°μ μ₯μ μ΄ μμ΅λλ€.
- 보μμ μμ ν¨
- νμ€ μΉ API μ¬μ©λ²μ μ€μ
- μ½λ μλκ° λͺ νν¨
- 곡μ λ¬Έμ(MDN, W3C λ±)μμλ κΆμ₯νλ λ°©μ
javascript:focus()μ λͺ©μ κ³Ό μ€ν΄
λ§μ κ°λ°μλ€μ΄ javascript:focus()λ₯Ό μ΄κΈ° URLλ‘ λ£λ μ΄μ λ λ€μκ³Ό κ°μ΅λλ€.
- λΉ μ°½μ μ΄ λ νμ μ΄ μ°¨λ¨λλ νμμ μ°ννλ €κ³
- μ°½μ μ° μ§ν μλμΌλ‘ ν¬μ»€μ€λ₯Ό μ£Όλ €κ³
νμ§λ§ μ΅μ λΈλΌμ°μ λ λ€μκ³Ό κ°μ νΉμ±μ΄ μμ΅λλ€.
- μ¬μ©μ ν΄λ¦ μ΄λ²€νΈ λ΄λΆμμ window.open()μ νΈμΆνλ©΄ λλΆλΆ μ°¨λ¨νμ§ μμ΅λλ€
- ν¬μ»€μ€κ° νμνλ€λ©΄ popup.focus()λ₯Ό λͺ μμ μΌλ‘ νΈμΆνλ κ²μ΄ ν¨μ¬ λ λͺ ννκ³ μμ ν©λλ€
- μΌλΆ μ΅μ λΈλΌμ°μ μμλ 보μ μ μ± μΌλ‘ μΈν΄ javascript: URLμ΄ μλνμ§ μμ μ μμ΅λλ€
μ¦, javascript:focus()λ κ³Όκ±°μλ ν΅νμμ§ λͺ°λΌλ, νλ μΉ λ³΄μ νκ²½μμλ μ μ νμ§ μμ λ°©μμ λλ€.
URL κ°μ²΄μ javascript: URLμ μμ ν λ€λ¦ λλ€
νΉμ URLμ΄λΌλ λ¨μ΄ λλ¬Έμ λ€μκ³Ό κ°μ λ¬Έλ²μ λ μ¬λ¦¬μ λΆλ κ³μ€ ν λ°μ?!
const url = new URL(window.location.href);
const tag = url.searchParams.get('tag');
μ΄κ±΄ URL μ 보λ₯Ό λΆμνκ³ μ‘°μνκΈ° μν κ°μ²΄λ‘, μ£Όμ νμ±μ μν΄ μμ£Ό μ μ©νκ² μ°μ λλ€. μλ₯Ό λ€μ΄ 쿼리 νλΌλ―Έν° μΆμΆ, κ²½λ‘ μ‘°μ λ±μ μμ£Ό μ¬μ©λ©λλ€.
λ°λ©΄ 'javascript:...'λ λΈλΌμ°μ μ μλ°μ€ν¬λ¦½νΈλ₯Ό μ§μ μ€ννλΌκ³ λͺ λ Ήνλ μ€ν΄μ΄κΈ° λλ¬Έμ, λͺ©μ λ μ°μλ μμ ν λ€λ¦ λλ€.
νλͺ©μ€λͺ - μ¬μ© μ©λ
new URL(...) | μ£Όμ νμ±μ μν URL κ°μ²΄ | μμ νκ³ νμ€μ μΈ λ°©λ² |
'javascript:focus()' | μ€ν μ½λλ₯Ό URLμ λ£λ λ°©μ | 보μμ μν, λΉκΆμ₯ λ°©μ |
λΆλͺ¨-μμ μ°½ κ΄κ³μ μ μ΄
window.open()μΌλ‘ μ΄λ¦° νμ μ λΆλͺ¨ νμ΄μ§μ λ°μ ν κ΄κ³λ₯Ό κ°μ§λλ€. μ΄λ₯Ό νμ©νκ±°λ μ£Όμν΄μΌ ν μ μ΄ μμ΅λλ€.
λΆλͺ¨ νμ΄μ§μμ μμ μ°½ μ μ΄νκΈ°
νμ μ μ° λΆλͺ¨ νμ΄μ§λ λ°νλ μ°Έμ‘°λ₯Ό ν΅ν΄ μμ μ°½μ μμ ν μ μ΄ν μ μμ΅λλ€.
const popup = window.open('about:blank', 'myPopup');
// μμ μ°½ λ΄μ© λ³κ²½
popup.document.body.innerHTML = '<h1>λΆλͺ¨κ° λ³κ²½ν λ΄μ©</h1>';
// μμ μ°½ ν¬κΈ°/μμΉ μ‘°μ
popup.resizeTo(500, 300);
popup.moveTo(100, 100);
// μμ μ°½ μ’
λ£
popup.close();
μμ μ°½ μ’ λ£ μλ리μ€
μ¬λ¬ μν©μμ μμ μ°½μ΄ μλμΌλ‘ μ’ λ£λ μ μμ΅λλ€.
- λΆλͺ¨ νμ΄μ§ μ΄λ λλ μλ‘κ³ μΉ¨ μ
// νμ΄μ§ μ΄λ μ μ μμ μ°½ λ«κΈ° window.addEventListener('beforeunload', () => { if (popup && !popup.closed) { popup.close(); } });
- λ€λ₯Έ SPA λΌμ°νΈλ‘ μ΄λ μ
// React Router λ±μ λΌμ°νΈ λ³κ²½ μ΄λ²€νΈμ μ°κ²° router.beforeEach((to, from, next) => { if (window.myPopup && !window.myPopup.closed) { window.myPopup.close(); } next(); });
μμ μ°½μ΄ λΆλͺ¨ νμ΄μ§ κ°μ§νκΈ°
μμ μ°½μμλ λΆλͺ¨ μ°½μ μ‘΄μ¬μ μνλ₯Ό νμΈν μ μμ΅λλ€.
// μμ μ°½μμ λΆλͺ¨ μ°½ νμΈ λ° λμνκΈ°
if (window.opener && !window.opener.closed) {
// λΆλͺ¨ μ°½μ΄ μ‘΄μ¬νκ³ μ΄λ €μμ
console.log('λΆλͺ¨ μ°½ URL:', window.opener.location.href);
} else {
// λΆλͺ¨ μ°½μ΄ λ«νκ±°λ μμ
console.log('λ
립μ μΌλ‘ μ€ν μ€');
}
λΈλΌμ°μ νΈνμ±κ³Ό μΆκ° κ³ λ €μ¬ν
μ΅μ λΈλΌμ°μ λ€μ window.open()μ λν΄ μ μ λ μ격ν μ μ± μ μ μ©νκ³ μμ΅λλ€.
- Chrome, Safari: μ¬μ©μ μ μ€μ²(ν΄λ¦ λ±) μμ΄ window.open()μ νΈμΆνλ©΄ μ°¨λ¨λ©λλ€
- Firefox: νμ μ°¨λ¨ μ€μ μ λ°λΌ λμμ΄ λ¬λΌμ§λλ€
- λͺ¨λ°μΌ λΈλΌμ°μ : λ§μ λͺ¨λ°μΌ λΈλΌμ°μ μμ νμ μ체λ₯Ό μ νμ μΌλ‘ μ§μν©λλ€
λ°λΌμ νμ λμ λͺ¨λ¬μ΄λ μΈλΌμΈ μ½ν μΈ λ₯Ό κ³ λ €νλ κ²λ μ’μ λμμ΄ λ μ μμ΅λλ€:
// νΉλ³ν μ΄μ κ° μλ€λ©΄ νμ
λμ λͺ¨λ¬μ κ³ λ €ν΄λ³΄μΈμ
document.getElementById('openModal').addEventListener('click', () => {
document.getElementById('myModal').style.display = 'block';
});
μμ½ λ° κ²°λ‘
- λͺ¨λ νλ μμν¬κ° μ£Όλ₯μΈ μ§κΈλ OAuth, κ²°μ μ°λ, νλ¦°νΈ κΈ°λ₯ λ±μ μν΄ window.open()μ΄ νμν μν©μ΄ μμ΅λλ€.
- javascript:focus() λ°©μμ 보μμ μννκ³ , MDN λ° ESLintμμλ μ¬μ©μ κΆμ₯νμ§ μμ΅λλ€.
- νμ μ μ΄ λλ about:blankλ λΉ λ¬Έμμ΄μ μ¬μ©νκ³ , κ·Έ μ΄νμ popup.location.hrefμ popup.focus()λ₯Ό μ¬μ©νλ λ°©μμ΄ κ°μ₯ νμ€μ μ΄κ³ μμ ν©λλ€.
- λΆλͺ¨ νμ΄μ§μμλ νμ μ°½μ μμ ν μ μ΄ν μ μμΌλ©°, νμ΄μ§ μ ν μ νμ μ°½μ μ μ ν κ΄λ¦¬(μ’ λ£)ν΄μΌ ν©λλ€.
- React κ°μ νλ μμν¬μμλ useRefμ useEffectλ₯Ό νμ©ν΄ νμ μ μλͺ μ£ΌκΈ°λ₯Ό μ»΄ν¬λνΈμ μ°λν μ μμ΅λλ€.
- URL κ°μ²΄μ javascript: URLμ κ°λ μ΄ μμ ν λ€λ₯΄λ―λ‘ νΌλνμ§ λ§μΈμ.
νΉμ μν©μμλ window.openμ΄ μ¬μ ν μ μ ν μ νμΌ μ μμ΅λλ€. μ΄λ° κ²½μ°μλ λ μμ ν λ°©μμΌλ‘ μ½λ©ν΄ 보μλ 건 μ΄λ¨κΉμ?!
κΆκΈνμ μ μ΄ μλ€λ©΄ μΈμ λ μ§ λκΈλ‘ λ¨κ²¨μ£ΌμΈμ!
π μ°Έκ³ λ¬Έν | ||
JAVASCRIPT.INFO - Popups and window methods | ||
W3 Schools - Window open() | ||
eslint/no-script-url | ||
MDN Web Docs | ||
Popup or Modal |
'TIL' μΉ΄ν κ³ λ¦¬μ λ€λ₯Έ κΈ
μΉ μ»΄ν¬λνΈμ μ΄λ²€νΈ μ²λ¦¬ (0) | 2024.11.25 |
---|