우리는 기록window.location.replace
을 피하고 페이지를 다시로드하지 않고 페이지 내 앵커 를 타겟팅 할 수 있지만 iframe에서는 사용할 수 없습니까?
문제는 인 CSP (콘텐츠 보안 정책)을 위반, 국가가 script-src 'unsafe-inline'
활성화되어 있어야합니다. CSP가 정의되어 있지 않고 예외를 정의하고 허용하더라도 script-src 'unsafe-inline'
여전히 동일한 위반 오류가 발생합니다. ie11 / chrome / ff와 동일한 결과입니다.
동일한 도메인 의 동일한 디렉토리 에있는 iframe
- 콘솔에서 iframe을 타겟팅하고 콘솔에서 사용하십시오
window.location.replace('/samepage.html#onpage_anchor')
. - 효과가있다. 페이지를 다시로드하지 않고 기록없이 페이지 내 앵커를 대상으로합니다.
- 앵커 링크에 동일한 코드를 인라인으로 넣으면 작동합니다.
- 동일한 코드를 사용하여 , 외부 스크립트 얻가 CSP 위반 오류. iframe에 없으면 잘 작동합니다.
나는 CSP를 만들려고 작업을 할 수 있도록하지만, 심지어 가장 관대 한 콘텐츠 보안 정책을 수는 그것을 허용합니다.
편집 : 그래서 여러 파일을 허용하는 plunker에 예제를 모아서 부모 / 자식 페이지를 참조하는 올바른 href를 사용할 수 있습니다 .
플런저 예제에 대한 참고 사항 :
이 예제에서는 문제가 재현되지 않습니다. 스크립트는 iframe에서도 완벽하게 작동합니다. 그러나 로컬 서버에서 또는 동일한 코드를 VPS에서 라이브로 실행할 때 동일한 코드가 작동하지 않습니다.
plunker가 일종의 추상화 계층을 통해 브라우저에 콘텐츠를 제공하기 때문에 plunker에서 CSP 위반이 트리거되지 않는 것 같습니다.
부모에서 아코디언 링크를 처음 클릭하면 새로 고침이 발생합니다. 페이지가 처음로드되는 방식이 index.html을 참조하지 않기 때문입니다. 후속 클릭은 페이지를 다시로드하지 않고 예상대로 작동합니다. 처음에 child.html을 참조하기 때문에 iframe에서 문제가되지 않습니다.
이것들은 코드가 작동하도록 변경하지 않고 코드를 보여주는 좋은 예입니다 (아래에 언급 된 스택 오버 플로우 스 니펫에서 href를 변경해야 함). Javascript가 정상적으로 작동하는 것을 보여주기 때문에 좋습니다. 그러나 실제로 문제를 나타내지는 않습니다. 여전히 실제 문제를 보려면 편집기에서 파일을로드하고 로컬 서버 또는 라이브 호스팅 환경에서 실행해야합니다.
플 런커 예
단순화 된 코드 예제
하나의 항목으로 간단한 아코디언. 문제를 재현하기에 충분합니다.
열기 / 닫기를 클릭하면 아코디언이 확장 / 축소되며 JS가 필요하지 않습니다. JS는 똑같은 일을하지만 역사는 없어야합니다. 잘 작동하지만 iframe에서는 작동하지 않습니다.
코드 스 니펫 노트 :
스 니펫을 실행하여 내가 설명하는 내용에 대한 아이디어를 얻을 수 있지만 실제로 문제를 보여주지는 않습니다.
스 니펫은 실제 브라우저에서와 같이 작동하지 않으며 자바 스크립트가 작동하지 않습니다.
스 니펫은 코드를 표시하지만 문제를 보려면 iframe에서 실행해야합니다. 차이점 과 작동 방식 을 보려면 iframe 외부에서 실행하십시오 .
- 링크가 (전체 URL을 교체)에 JS 작업 방법 때문에 그들은 실제로 해야한다 이렇게 될
href="https://stackoverflow.com/thispage.html#ac1"
오히려보다는 다만href="#ac1"
그들이 조각에 나타나는 (스 니펫의 실제 HTML 페이지를 타겟팅 할 수 없습니다). 당신이 경우에 따라서 편집기에서 이것을 시도 (제발), 다음 기억 이 형식에 대한 링크를 변경this_document.html#anchor
그들은 여전히 그래서 같은 페이지 앵커, 하지만 page.html이 링크에 포함되어 있습니다.
스크립트
$(document).ready(function() {
// anchor links without history
$.acAnch = function(event) {
event.preventDefault();
var anchLnk = $(event.target);
var anchTrgt = anchLnk.attr('href');
window.location.replace(anchTrgt);
}
// listen for anchor clicks
$('.accordion').on('click', 'a', $.acAnch);
});
이것은 매우 간단합니다.
1. acAnch 함수는 href
속성을 가져 와서에 놓습니다 window.location.replace()
.
2. 아코디언 내에서 앵커를 클릭하여 acAnch 기능을 실행하십시오.
모든 스크립트가 실행됩니다 window.location.replace('/this_same_page.html#on_page_anchor')
콘솔에 넣으면 CSP 위반이 발생하지 않습니다. 그러나 외부 스크립트에서 실행하면 작동하지 않습니다.
링크의 인라인은 정상적으로 작동합니다.
onclick="event.preventDefault();window.location.replace('/thispage.html#acc0');"
onclick="event.preventDefault();window.location.replace('/thispage.html#acc1');"
각 링크에 넣는 것이 완벽하게 작동 하지만 인라인 스크립트를 사용하지 않는 것이 좋습니다. 외부 스크립트를 사용하여 이를 수행 할 수있는 방법이 있어야합니다 .
iframe 대신 부모에서 자바 스크립트를 실행하려고했습니다 (물론 자식 내에서 링크를 선택하도록 수정). 동일한 CSP 오류 결과.
내가 왜 이러는거야?
사이트는 예제보다 훨씬 복잡합니다. iframe의 앵커는 정상적으로 작동하지만 기록 을 추가합니다. 자바 스크립트없이 위의 코드를 실행하거나 코드 조각을 실행하고 아코디언을 몇 번 열고 닫은 다음 뒤로 버튼을 사용하면 열린 닫기 상태로 돌아갑니다.
나는 역사를 신경 쓰지 않을 것이지만 그것이 iframe에 있다면 부모 페이지를 떠났다가 다시 돌아올 때 iframe의 역사가 깨집니다. 돌아가는 것은 더 이상 아코디언 상태를 거꾸로 돌아 가지 않고 대신 iframe을 계속 다시로드합니다. 처음에는 앵커가 iframe을 다시로드가 발생하지 않습니다하지만 단지 아코디언 상태 역사, 단계 , 벌금을 작동 페이지를 떠나 다시 올 때까지. 그런 다음 다시 는 더 이상 아코디언 상태를 거치지 않지만 동일한 iframe 재로드 더미를 거치게 됩니다. 매우 사용자 친화적이지 않은 행동입니다.
작동하는 다른 방법이 있으면 location.replace를 사용할 필요가 없습니다. 나는 많은 다른 접근법을 시도했지만 동일한 결과를 얻을 수있는 방법, 일반적으로 동일한 오류가 발생한다는 것을 알았습니다.
목표는 단순히 iframe 내에서 다시로드하지 않고 기록없이 페이지에서 앵커 링크 를 활성화하는 것 입니다.
인라인 스크립트가 작동합니다. 외부 .js 파일에서 작동시킬 수 있습니까?
<a href="#ac0" class="ac-close">Close</a>
작동해야합니다.