테스트 페이지 : https://jsfiddle.net/y25rk55w/
이 테스트 페이지에서 3 개가 <iframe>
서로 삽입 된 것을 볼 수 있습니다 . 각각 <iframe>
의 <script>
태그 에는 <head>
태그가 있습니다.
문제는<script>
첫 번째 파일 만 <iframe>
브라우저에 의해로드된다는 것입니다. 다른 두 개의 <script>
태그는 dom에 있지만 브라우저는로드를 시도하지도 않습니다. 문제는 브라우저에만 국한된 것이 아니며 크롬, 파이어 폭스 등에서 줄일 수 있습니다. 제한 시간을 추가하거나 스크립트를 추가하기 전에 대기하여 문제를 해결할 수 없습니다. 모든 iframe에 프로그래밍 방식으로 생성 된 콘텐츠가있는 것이 중요해 보입니다. 이 iframe을 실제 src 링크가있는 iframe으로 바꾸면 문제가 사라집니다.
질문은 iframe 2와 3에 실제로 스크립트를로드하는 방법 입니다.
전체 테스트 코드 :
// It doesn't matter if the scripts exist or not
// Browser won't try to load them either way
var scripts = [
'//testdomain.test/script1.js',
'//testdomain.test/script2.js',
'//testdomain.test/script3.js'
];
function createIFrame(win, onCreated) {
var iframe = win.document.createElement('iframe');
iframe.onload = function () {
onCreated(iframe);
};
win.document.body.appendChild(iframe);
}
function loadScript(win, url) {
var script = win.document.createElement('script');
script.src = url;
script.onload = function() {
console.log("Script " + url + " is loaded.");
};
win.document.getElementsByTagName('head')[0].appendChild(script);
}
createIFrame(window, function(iframe1) {
loadScript(iframe1.contentWindow, scripts[0]);
createIFrame(iframe1.contentWindow, function (iframe2) {
loadScript(iframe2.contentWindow, scripts[1]);
createIFrame(iframe2.contentWindow, function (iframe3) {
loadScript(iframe3.contentWindow, scripts[2]);
});
});
});
질문에서 내가 프로토콜을 생략하고 있음을 알 수 있습니다.
/* This is valid to omit the http:/https: protocol.
In that case, browser should automatically append
protocol used by the parent page */
var scripts = [
'//testdomain.test/script1.js',
'//testdomain.test/script2.js',
'//testdomain.test/script3.js'
];
문제는 프로그래밍 방식으로 생성 된 iframe에 프로토콜 about:
(또는 javascript:
생성 방법에 따라)이 있다는 것입니다. 여전히 첫 번째 스크립트가로드되는 이유 또는 다른 두 스크립트가 네트워크 탭에 전혀 표시되지 않는 이유를 설명 할 수 없지만 그다지 중요하지 않은 것 같습니다.
해결책 : 명시 적으로 사용 https://
하거나 다음 코드와 같은 것을 사용하여 프로토콜을 프로그래밍 방식으로 추가합니다.
function appendSchema(win, url) {
if (url.startsWith('//')) {
var protocol = 'https:';
try {
var wPrev = undefined;
var wCur = win;
while (wPrev != wCur) {
console.log(wCur.location.protocol);
if (wCur.location.protocol.startsWith("http")) {
protocol = wCur.location.protocol;
break;
}
wPrev = wCur;
wCur = wCur.parent;
}
} catch (e) {
/* We cannot get protocol of a cross-site iframe.
* So in case we are inside cross-site iframe, and
* there are no http/https iframes before it,
* we will just use https: */
}
return protocol + url;
}
return url;
}
이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.
침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제
몇 마디 만하겠습니다