๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ
๐Ÿ’ก issue

Safari ๋ธŒ๋ผ์šฐ์ € window.open block ์ด์Šˆ

by HandHand 2022. 11. 26.

 

๐Ÿ“Œ 1:1 ๋ฌธ์˜ํ•˜๊ธฐ๊ฐ€ safari ์—์„œ๋งŒ ๋™์ž‘์„ ์•ˆํ•ด์š”!

์–ผ๋งˆ์ „์— ํ•ญ๊ณต์ชฝ QA ์ค‘์— ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์ด์Šˆ๊ฐ€ ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค.

 

 

์›์ธ์„ ํŒŒ์•…ํ•˜๊ธฐ์œ„ํ•ด safari ๋ธŒ๋ผ์šฐ์ €์—์„œ ๋™์„ ์„ ํŒŒ์•…ํ•ด๋ณด๋‹ˆ,

๋ฌธ์˜ ๋ฒ„ํŠผ ํด๋ฆญ ์‹œ ์ƒˆ์ฐฝ์œผ๋กœ ์—ด๊ธฐ ๋Œ€์‹  ํŒ์—… ์ฐจ๋‹จ ์•Œ๋Ÿฟ์ด ๋œจ๋Š” ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค.

 

๐Ÿค” ์›์ธ์ด ๋ญ˜๊นŒ?

safari ๋ธŒ๋ผ์šฐ์ €์—์„œ ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์ฝ”๋“œ๋Š” ์ •์ƒ์ ์œผ๋กœ ๋™์ž‘ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

<button onClick={async () => {
  await asyncJob()
  window.open('url', '_blank'); // โŒ
} />

์ด๋Š” safari ๋ธŒ๋ผ์šฐ์ €์—์„œ ์ƒˆ์ฐฝ์„ ์—ด๋•Œ, ์‚ฌ์šฉ์ž์˜ ์ž…๋ ฅ์— ๊ณง๋ฐ”๋กœ ๋ฐ˜์‘ํ•  ์ˆ˜ ์—†๋Š” ์ƒํ™ฉ์ด๋ผ๋ฉด

window.open ์•ก์…˜์„ ๋ง‰๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค.

(๋Œ€ํ‘œ์ ์œผ๋กœ ๋น„๋™๊ธฐ ์š”์ฒญ์„ ์ˆ˜ํ–‰ํ•œ ๋’ค ๋ฆฌ๋‹ค์ด๋ ‰ํŠธ ํ•˜๋Š” ๊ฒƒ์ด ์žˆ๊ฒ ๋„ค์š”)

 

๐Ÿ“Œ ์–ด๋–ป๊ฒŒ ๊ณ ์น˜๋ฉด ๋ ๊นŒ?

๐Ÿ› ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•œ ์ฝ”๋“œ

๊ธฐ์กด์—๋Š” ์ƒˆ์ฐฝ์œผ๋กœ ์—ด๊ธฐ ์ „์— API ํ˜ธ์ถœ์„ ํ†ตํ•ด์„œ ๊ณ ๊ฐ ID ๋ฅผ ๋ถˆ๋Ÿฌ์™€

์ด๋™ํ•˜๋ ค๋Š” ๊ณ ๊ฐ๋ฌธ์˜ ํŽ˜์ด์ง€ URL์— ์‚ฝ์ž…ํ•˜๋Š” ๋กœ์ง์ด ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค.

const handleRedirectToCsPage = async () => {
	const { uid } = await fetchUserId()

	window.open(`cs/${uid}/...`, '_blank')
}

<button onClick={handleRedirectToCsPage}>๊ณ ๊ฐ๋ฌธ์˜</button>

 

๐Ÿ”จ ๋ฆฌํŒฉํ† ๋งํ•˜๊ธฐ

๊ทผ๋ฐ uid ๋Š” ์‚ฌ์‹ค ํ˜ธ์ถœํ•˜๋Š” ์‹œ์ ์— ๋ถˆ๋Ÿฌ์˜ฌ ํ•„์š”๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค.

ํŠน์ • ์กฐ๊ฑด์— ๋”ฐ๋ผ ๋™์ ์œผ๋กœ ๋ฐ”๋€Œ๋Š” ๊ฐ’์ด ์•„๋‹ˆ๊ธฐ ๋•Œ๋ฌธ์—, ํŽ˜์ด์ง€ ๋กœ๋“œ ์‹œ์ ์— ๋ถˆ๋Ÿฌ์™€ ์„ค์ •ํ•˜๋ฉด ๋˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

๋‹ค๋งŒ uid ๋ฅผ ๋ถˆ๋Ÿฌ์˜ค์ง€ ์•Š์€ ์ƒํƒœ์—์„œ๋Š” ๊ณ ๊ฐ๋ฌธ์˜ ํŽ˜์ด์ง€์— ์ ‘๊ทผ์„ ๋ง‰์•„์•ผํ•˜๊ธฐ์—

๋ฐฉ์–ด ๋กœ์ง๋งŒ ์ถ”๊ฐ€ํ•ด์ฃผ๋Š” ๋ฐฉํ–ฅ์œผ๋กœ ์ฝ”๋“œ๋ฅผ ๋ณ€๊ฒฝํ–ˆ์Šต๋‹ˆ๋‹ค.

 

const [uid, setUid] = useState() // โœ… cs user id ๋ฅผ ์ €์žฅํ•  ์ƒํƒœ๊ฐ’์ถ”๊ฐ€

const handleRedirectToCsPage = () => {
	if (uid) {
		window.open(`cs/${uid}/...`, '_blank') // โœ… ์ผ๋ฐ˜ ํ•จ์ˆ˜๋กœ ๋ณ€๊ฒฝํ•˜๊ณ  uid ์ฒดํฌ!
	}
}

useEffect(() => {
	const fetchAndSetUid = async () {
		const { uid } = await fetchUserId()
		setUid(uid) // โœ… ํŽ˜์ด์ง€ ๋กœ๋“œ ์ดํ›„์— ๋น„๋™๊ธฐ๋กœ ์„ค์ •
	}

	fetchAndSetUid()
}, [])

<button onClick={handleRedirectToCsPage}>๊ณ ๊ฐ๋ฌธ์˜</button>

 

๐Ÿ’ก ๊ทธ์™ธ์— ์•Œ์•„๋‘๋ฉด ์ข‹์€ ๋‹ค๋ฅธ ๋ฐฉ๋ฒ•

์ด๋Ÿฌํ•œ ๋ฌธ์ œ๋ฅผ ์šฐํšŒํ•˜๋Š” ๋‹ค๋ฅธ ๋ฐฉ๋ฒ•์€ ๋น„์–ด์žˆ๋Š” ์ƒˆ์ฐฝ์„ ์—ด๊ณ , ๋น„๋™๊ธฐ ๋กœ์ง ์ˆ˜ํ–‰์ด ๋๋‚˜๊ธฐ๋ฅผ ๊ธฐ๋‹ค๋ฆฐ ๋’ค์—

ํ•ด๋‹น ๋น„์–ด์žˆ๋Š” ์ฐฝ์— ์ด๋™ํ•  ์ฃผ์†Œ๋ฅผ ํ• ๋‹นํ•ด์ฃผ๋Š” ๋ฐฉ๋ฒ•๋„ ์žˆ์Šต๋‹ˆ๋‹ค.

์ด๋ฒˆ์—๋Š” ์ด๋ ‡๊ฒŒ ํ•˜์ง€ ์•Š์•„๋„ ๋ฆฌํŒฉํ† ๋ง์œผ๋กœ ๊ฐ„๋‹จํ•˜๊ฒŒ ํ•ด๊ฒฐ์ด ๋˜๋Š” ๋ฌธ์ œ์˜€๊ธฐ ๋•Œ๋ฌธ์—

๋‚˜์ค‘์— ๋น„์Šทํ•œ ์ด์Šˆ๊ฐ€ ์ƒ๊ธด๋‹ค๋ฉด ๊ณ ๋ คํ•ด๋ด์•ผ๊ฒ ๋„ค์š”.

on('click', () => {
	const open = window.open('about:blank', '_blank')
	
	setTimeout(() => open.location.href == '<https://somepath.com>', 500)
})

์—ฌ๊ธฐ์„œ๋Š” ์˜ˆ์‹œ๋ฅผ ์œ„ํ•ด ๋น„๋™๊ธฐ ๋™์ž‘์„ setTimeout ์œผ๋กœ ํ–ˆ์ง€๋งŒ,

API ํ˜ธ์ถœ์ด๋‚˜ ๊ธฐํƒ€ ๋‹ค๋ฅธ ๋กœ์ง๋“ค๋กœ๋„ ๋Œ€์ฒดํ•  ์ˆ˜ ์žˆ์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

 

๐Ÿ“Œ ์ฐธ๊ณ ์ž๋ฃŒ

https://github.com/microsoft/vscode/issues/118731

Why open link is not working inside a async handler on iPad Safari?

Problem related to window.open() on Safari

window.open(url, '_blank'); not working on iMac/Safari

๋ฐ˜์‘ํ˜•

๐Ÿ’ฌ ๋Œ“๊ธ€