From 51496b976e831d3b840a77e183282d382258f13b Mon Sep 17 00:00:00 2001 From: chpark Date: Sun, 29 Mar 2026 23:52:31 +0900 Subject: [PATCH] =?UTF-8?q?fix:=20=EB=B9=84=EC=A3=BC=EC=96=BC=20=EB=A7=A4?= =?UTF-8?q?=ED=8D=BC=20iframe=20=EC=8A=A4=ED=81=AC=EB=A6=BD=ED=8A=B8=20?= =?UTF-8?q?=EC=8B=A4=ED=96=89=20+=20Mixed=20Content=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - sandbox에 allow-scripts 추가 - HTTP 리소스 URL을 HTTPS로 자동 변환 - fetch-page API 직접 호출로 에러 처리 개선 --- views/admin/mapper.ejs | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/views/admin/mapper.ejs b/views/admin/mapper.ejs index 2d3fdd6..1a21e51 100644 --- a/views/admin/mapper.ejs +++ b/views/admin/mapper.ejs @@ -27,7 +27,7 @@ - +
URL을 입력하고 "페이지 가져오기"를 클릭하세요
@@ -134,7 +134,12 @@ async function fetchPage() { document.getElementById('status-bar').textContent = '페이지 로딩 중...'; try { - var res = await api('POST', '/api/fetch-page', { url: url }); + var resp = await fetch('/api/fetch-page', { + method: 'POST', headers: {'Content-Type':'application/json'}, credentials: 'same-origin', + body: JSON.stringify({ url: url }) + }); + if (!resp.ok) { var err = await resp.json().catch(function(){return {error:'HTTP '+resp.status}}); throw new Error(err.error || 'HTTP '+resp.status); } + var res = await resp.json(); if (res.error) throw new Error(res.error); var frame = document.getElementById('preview-frame'); @@ -145,6 +150,10 @@ async function fetchPage() { var baseTag = ''; html = html.replace(/]*)>/i, '' + baseTag); + // Mixed Content 방지: http → https 변환 (리소스 URL만) + html = html.replace(/(src|href|action)=(["'])http:\/\//gi, '$1=$2https://'); + html = html.replace(/url\((['"]?)http:\/\//gi, 'url($1https://'); + // iframe에 매퍼 스크립트 주입 var mapperScript = getMapperScript(); html = html.replace(/<\\/body>/i, mapperScript + '');