2013-04-15 2 views
1

설정 :크로스 프레임 크로스 사이트 스크립팅 - 웹 페이지 장전을 생성/감시

원격 측정 스테이션은 중앙 집중식 수집/처리/프리젠 테이션 서버 (웹 서버와 함께)가있다 및 관측소가 고객을 위해 수집 된 데이터를 표시합니다.

이러한 관측 스테이션은 베어 본으로 구성되며 간단한 내장 컴퓨터로 키오스크 모드에서 작동하는 웹 브라우저가 장착되어 중앙 서버에서 각각 특정 웹 페이지를 표시합니다. 이 웹 페이지는 주어진 측정 스테이션의 최신 측정 값을 표시하는 AJAX로 업데이트됩니다. 고정 된 모니터에 연결되면 이러한 스테이션은 수년간 거의 유지 보수가 필요 없습니다.

이제 우리는 대부분의 꼬임을 해결했지만 문제가 있습니다. 웹 서버에 장애가 발생하면 어떻게해야합니까? 브라우저는 "도달 할 수 없음", "404", "권한 거부", "500"또는 그 시점에서 서버가 발생한 모든 모드를로드하고 누군가가 관측 스테이션을 수동으로 재부팅 할 때까지 그곳에 머물러 있습니다.

제가 생각해 낸 일반적인 해결책은 브라우저의 홈 페이지를 관찰 된 페이지가 아닌 항상 사용할 수있는 로컬 HTML 파일로 설정하는 것입니다.이 HTML 파일은 원격 페이지가로드되고 올바르게 업데이트되는지 정기적으로 확인하고 다시로드합니다 그것은 어떤 이유로 든 수행하지 못하면 그것.

문제점 :

문제가 프레임 간 스크립팅에있다. 대상 웹 페이지가 프레임, iframe, 텍스트/HTML 형식의 개체 또는 로컬 "컨테이너"파일을 제거/사용하지 않고 표시되도록하는 다른 방법으로로드해야합니다. 몇 년 전에 크로스 프레임 스크립팅 페이지를 작성했고 보안 대책을 우회하는 것은 쉽지 않았습니다. 그 이후로 보안이 강화되었을 것입니다.

그래서, 원격 서버에서로드 된 페이지는 모든 것이 잘 된 경우 (일부에서는 setInterval) 주기적으로 시작, 또는 문제가 생겼 경우하지 않습니다되는 자바 스크립트의 조각이 포함되어 있습니다. 이 신호가 컨테이너 프레임에 주기적으로 도착하면 타임 아웃이 재설정되고 다른 작업은 수행되지 않습니다.

신호가 도착하지 않으면 제한 시간이 만료됨에 따라 컨테이너가로드되고로드 된 웹 페이지가 주기적으로 새로 고쳐지고 서버가 고정되어 적절한 컨텐트가로드되어 로더에 신호를 보냅니다.

가 어떻게 파일에서로드 지역 (컨테이너) 페이지 (변수를 설정, 말) 원격 페이지는 "살아"신호를받을 수 있나요 : // URL마다 특정 기능 트리거?

답변

0

크로스 프레임, 크로스 사이트 통신 방법은 postMessage를 사용합니다.

포함 된 프레임, 각각의 올바른 실행에 수행해야합니다

window.top.postMessage('tyrp', '*'); 

컨테이너 문서에 포함되어 있어야합니다. 기본적으로 어떤 SF의 답변을하지 porthole라는 라이브러리가있다

window.onmessage = function(e) 
{ 
    if (e.data == 'tyrp') { 
     //reset timeout here 
    } 
}; 
2

더 공식적인 형태로 설명되어 있습니다. 방금 두 개의 iframe 중 하나를 표시하도록 전환 할 웹 페이지를 작성했습니다. 최상위 웹 페이지에는

var windowProxy; 
windowProxy = new Porthole.WindowProxy(baseURL + '/porthole/proxy.html', frameId); 
windowProxy.addEventListener(onMessage); 
... 
function onMessage(messageEvent) { 
    if (messageEvent.origin !== baseURL) { 
     $log.error(logPrefix + ': onMessage: invalid origin'); 
     console.dir(messageEvent); 
     return; 
    } 
    if (messageEvent.data.pong) { 
     pongReceived(); 
     return; 
    } 
    $log.log(logPrefix + ': onMessage: unknown message'); 
    console.dir(messageEvent); 
} 
... 
var sendPing = function() { 
    $log.log(logPrefix + ': ping to ' + baseURL); 
    ... 
    windowProxy.post({ 'ping': true }); 
}; 

과 몇 가지 추가 제어 로직을 더한 것입니다.

// This service takes care of porthole (https://github.com/ternarylabs/porthole) 
// communication if this is invoked from a parent frame having this web page 
// as a child iframe. Usage of porthole is completely optional, and should 
// have no impact on anything outside this service. The purpose of this 
// service is to enable some failover service to be build on top of this 
// using two iframes to switch between. 
services.factory('portholeService', ['$rootScope', '$log', '$location', function ($rootScope, $log, $location) { 
    $log.log('Hello from portholeService'); 

    function betterOffWithFailover() { 
     ... 
    } 

    function onMessage(messageEvent) { 
     $rootScope.$apply(function() { 
      if (messageEvent.origin !== baseUrl) { 
       $log.error('onMessage: invalid origin'); 
       console.dir(messageEvent); 
       return; 
      } 

      if (!messageEvent.data.ping) { 
       $log.error('unknown message'); 
       console.dir(messageEvent.data); 
       return; 
      } 

      if (betterOffWithFailover()) { 
       $log.log('not sending pong'); 
       return; 
      } 

      windowProxy.post({ 'pong': true }); 
     }); 
    } 

    var windowProxy; 
    var baseUrl; 
    function init() { 
     baseUrl = $location.protocol() + '://' + $location.host() + ':' + $location.port(); 
     windowProxy = new Porthole.WindowProxy(baseUrl + '/porthole/proxy.html'); 
     windowProxy.addEventListener(onMessage); 
    } 

    return { 
     init: init 
    }; 
}]); 

참고로이 페이지 등의 경우 $rootScope.$applyAngularJS을 당신에게 익숙하고 사용 : 아이 웹 페이지에서 다음 내가 추가 한 모든 (플러스 컨트롤러에서 portholeService.init()를 호출)입니다.