2011-08-18 3 views
1

나는 페이지가 'virtualcasa1'도메인 모달 대화 상자 열기에서 호스팅 한 :셰어 : commonModalDialogClose 대화 크로스 도메인을 닫지 않습니다

var options = { 
    title: "Repro", 
    width: 400, 
    height: 600, 
    url: http://domain2:999/sites/blank/_layouts/XDomainTest/XDomainTestTarget.aspx //[1] 
    //url: http://virtualcasa1/sites/blank/_layouts/XDomainTest/XDomainTestTarget.aspx [2] 
}; 
SP.UI.ModalDialog.showModalDialog(options); 

을 그리고 나는 그것을 닫으이 코드를 가지고 :

alert(document.domain); 
SP.UI.ModalDialog.commonModalDialogClose(SP.UI.DialogResult.cancel, 'Cancelled clicked'); 

둘 다 동일한 도메인에 있으면 (위의 case [2]) 대화 상자가 잘 닫히고 아무런 문제가 없습니다.

하지만 -. 대상 페이지 대화에서 호스팅되는 경우 (경우 [1] 이상), 대화 상자가 위의 document.domain

페이지가 존재하는 올바른 도메인을 표시하지 가까운 :-(을 수행

내가 의심 나는 (대만족) 여기에 크로스 도메인 문제에 직면하고있어,하지만 해결 방법을 또는 내가 잘못하고 문제가 XDomain 관련되지 않은하는

감사를 많이

답변

0

내가 가지고 정확히 같은 문제를?! - 항목의보기 페이지를 여는 대화 상자가 사이트 공동체에서 열면 잘 작동합니다. 동일한 웹 응용 프로그램/도메인에서 웹 응용 프로그램을 실행하지만 별도의 웹 응용 프로그램에서 호스팅되는 사이트 모음에서 동일한 항목을 열면 닫기 단추가 작동하지 않습니다. 나는이 문제를 해결하기 위해 솔루션을 변경 했으므로이 문제를 100 % 만족하지는 못했지만, 전체 솔루션을 사용하기에 약간 어색함을 느끼지는 않습니다. 원근법. 나는 문제를 프로젝트 시간축으로 인해 한쪽으로 치우 쳤지 만, 나는 여전히 왜 그런지 궁금하다. 내가 생각할 수있는 유일한 사항은 XSS 보안 구멍을 막기 위해 설계된 전체 도메인 간 문제 때문일 수 있습니다.

3

HTML5의 게시물 메시지가 귀하의 답변입니다. 확인을위한

function listener(event) { 
    //alert(event.data); 
    if (event.data == 'Cancel') { 
    SP.UI.ModalDialog.commonModalDialogClose(SP.UI.DialogResult.cancel, 'Cancel clicked'); 
    } 
    else { 
    SP.UI.ModalDialog.commonModalDialogClose(SP.UI.DialogResult.OK, event.data); 
    } 
} 

if (window.addEventListener) { 
    addEventListener("message", listener, false) 
} else { 
    attachEvent("onmessage", listener) 
} 

자바 스크립트와 팝업 취소] 버튼 :로부터

<input type="button" value="OK" onclick="parent.postMessage('Message to be displayed by the parent', '*');" class="ms-ButtonHeightWidth" /> 
<input type="button" value="Cancel" onclick="parent.postMessage('Cancel', '*');" class="ms-ButtonHeightWidth" /> 
0

아제의 대답 대화는 다음과 같은 자바 스크립트가 있어야 시작

https://developer.mozilla.org/en-US/docs/Web/API/Window.postMessage

당신의 부모 창 2014 년 8 월 1 일이 좋지만 더 많은 설명이 필요합니다. 대화 상자를 닫지 못하는 이유는 간단합니다. 최신 브라우저의 교차 사이트 스크립팅 보안 기능은 몇 가지 사항을 허용하지 않습니다. 그 중 하나는 프레임 윈도우에서 window.frameElement를 사용하는 것입니다. 이것은 윈도우 객체의 읽기 전용 속성이며 null로 설정됩니다 (또는 IE에서 실제로 액세스하려고하면 예외가 발생 함). 모달 대화 상자의 일반 Cancel 이벤트 핸들러는 window.frameElement.cancelPopup()을 호출하여 종료됩니다. 이것은 물론 실패합니다. Save가 서버 측에서 작동하는 일반적인 Save 처리기는 SharePoint가 대체 문서로 단일 행을 보냄으로써 결과적으로 window.frameElement.commitPopup()을 호출하는 스크립틀릿입니다. 이것은 또한 작동하지 않으며, 페이지가 다시로드되고 아무 것도 처리 할 수있는 스크립트가 없기 때문에 극복해야 할 고통이 있습니다. XSS는 호출 페이지에서 프레임 된 DOM에 대한 액세스를 제공하지 않습니다.

크로스 도메인 호스팅 양식을 원활하게 작동 시키려면 대화 상자를 여는 페이지와 프레임 된 페이지 모두에 스크립트를 추가해야합니다. 대화 상자를 여는 페이지에서 Ajay가 제안한대로 메시지 수신기를 설정합니다.

(function() { 
    $(document).ready(function() { 
     var frameElement = null; 
     // Try/catch to overcome IE Access Denied exception on window.frameElement 
     try { 
      frameElement = window.frameElement; 
     } catch (Exception) {} 

     // Determine that the page is hosted in a dialog from a different domain 
     if (window.parent && !frameElement) { 
      // Set the correct height for #s4-workspace 
      var frameHeight = $(window).height(); 
      var ribbonHeight = $('#s4-ribbonrow').height(); 
      $('#s4-workspace').height(frameHeight - ribbonHeight); 

      // Finds the Save and Cancel buttons and hijacks the onclick 
      function applyClickHandlers(theDocument) { 
       $(theDocument).find('input[value="Cancel"]').removeAttr('onclick').on('click', doTheClose); 
       $(theDocument).find('a[id="Ribbon.ListForm.Edit.Commit.Cancel-Large"]').removeAttr('onclick').removeAttr('href').on('click', doTheClose); 
       $(theDocument).find('input[value="Save"]').removeAttr('onclick').on('click', doTheCommit); 
       $(theDocument).find('a[id="Ribbon.ListForm.Edit.Commit.Publish-Large"]').removeAttr('onclick').removeAttr('href').on('click', doTheCommit); 
      } 

      // Function to perform onclick for Cancel 
      function doTheClose(evt) { 
       evt.preventDefault(); 
       parent.postMessage('Cancel', '*'); 
      } 

      // Function to perform onclick for Save 
      function doTheCommit(evt) { 
       evt.preventDefault(); 

       if (!PreSaveItem()) return false; 
       var targetName = $('input[value="Save"]').attr('name'); 
       var oldOnSubmit = WebForm_OnSubmit; 
       WebForm_OnSubmit = function() { 
        var retVal = oldOnSubmit.call(this); 
        if (retVal) { 
         var theForm = $('#aspnetForm'); 
         // not sure whether following line is needed, 
         // but doesn't hurt 
         $('#__EVENTTARGET').val(targetName); 
         var formData = new FormData(theForm[0]); 
         $.ajax(
         { 
          url: theForm.attr('action'), 
          data: formData, 
          cache: false, 
          contentType: false, 
          processData: false, 
          method: 'POST', 
          type: 'POST', // For jQuery < 1.9 
          success: function(data, status, transport) { 
           console.log(arguments); 
           // hijack the response if it's just script to 
           // commit the popup (which will break) 
           if (data.startsWith('<script') && 
            data.indexOf('.commitPopup()') > -1) 
           { 
            parent.postMessage('OK', '*'); 
            return; 
           } 

           // popup not being committed, so actually 
           // submit the form and replace the page. 
           theForm.submit(); 
          } 
         }).fail(function() { 
          console.log('Ajax post failed.'); 
          console.log(arguments); 
         }); 
        } 

        return false; 
       } 
       WebForm_DoPostBackWithOptions(
        new WebForm_PostBackOptions(targetName, 
               "", 
               true, 
               "", 
               "", 
               false, 
               true) 
       ); 
       WebForm_OnSubmit = oldOnSubmit; 
      } 

      applyClickHandlers(document); 
     } 
    }); 
})(); 

이 솔루션은 우리 조직이 광범위하게 사용하는 jQuery 라이브러리, 사용한다 : 프레임이 양식 페이지에서는 다음과 같은 것을해야합니다. 그것은 우리가 선호하는 프레임 워크입니다 (저의 선택). 나는 매우 똑똑한 누군가가 의존성이없이 이것을 다시 작성할 수있을 것이라고 확신하지만 이것은 좋은 출발점이다. 나는 누군가가 그것이 좋은 이틀의 일을 대표하는 것으로서 유용하다고 생각하기를 바란다. 참고 사항 :

SharePoint는 페이지를 편집 모드로 설정하는 것을 포함하여 페이지의 모든 이벤트에 대해 다시 게시를 수행합니다. 이 때문에 예를 들어 글로벌 WebForm_OnSubmit 함수를 다시 정의하지 않고 양식과 리본 모두에서 특정 단추 클릭을 트랩하는 것이 더 효과적입니다. 저장 클릭시 해당 설정을 간단히 무시한 다음 다시 설정합니다.

클릭 저장 이벤트에서 우리는 양식의 일반적인 게시를 무효화하고 AJAX를 사용하여 동일한 POST 요청으로 대체합니다. 이렇게하면 폼이 성공적으로 게시 될 때 반환 된 스크립틀릿을 삭제할 수 있습니다. 비어있는 필수 값 때문에 양식 제출이 실패한 경우 페이지를 업데이트 할 수 있도록 양식을 올바르게 게시하기 만합니다. 양식이 처리되지 않았으므로 괜찮습니다. 이 솔루션의 이전 버전은 결과 HTML 문서를 가져 와서 모든 페이지 내용을 대체했지만 Internet Explorer는이 점을 좋아하지 않습니다.

FormData API를 사용하면 post the form as multipart-mime을 사용할 수 있습니다. 이 API는 모든 최신 브라우저에서 최소한 기본 지원을 제공하며 오래된 API에 대한 해결 방법이 있습니다.

크로스 도메인 호스팅 대화 상자에서 실패한 것으로 보이는 또 다른 사항은 콘텐츠 창을 스크롤하는 것입니다. 어떤 이유로 든 id가 s4-workspace 인 div에서 높이가 올바르게 설정되지 않았으므로 솔루션에서도이를 설정합니다.

편집 : 거의 잊어 버렸습니다.

< WebPartPages : AllowFraming RUNAT = "서버"/ >

또한 SharePoint 디자이너와 함께 할 수있는 프레임 ASPX 페이지에이 컨트롤을 추가해야 할 수 있습니다
관련 문제