设定:
有远程测量站,有集中收集/处理/演示服务器(带网络服务器),还有观察站,可以为客户显示收集的数据。
这些观察站由简单的嵌入式计算机组成,配备有在浏览器模式下工作的网络浏览器,每个显示来自中央服务器的一个特定网页。该网页使用AJAX进行更新,显示给定测量站的最新测量值。连接到固定监视器,这些站点几乎可以免维护多年。
现在我们已经解决了大部分问题,但问题在于:如果网络服务器出现故障怎么办? 浏览器将加载“无法访问”,“404”,“权限被拒绝”,“500”或服务器在此时采取的任何故障模式,并保留在那里直到有人手动重新启动观察站。
我提出的一般解决方案是将浏览器的主页设置为不是观察到的页面,而是设置为始终可用的本地HTML文件,如果远程页面已加载并正确更新,则会执行定期检查,并重新加载如果因任何原因无法执行。
问题:
问题在于跨框架脚本。我想目标网页必须加载为框架,iframe,文本/ HTML类型的对象,或其他一些方式,使其显示而不删除/禁用本地“容器”文件。几年前我写了一个跨框架脚本页面,规避安全措施并不容易。从那以后,必须加强安全。
因此,从远程服务器加载的页面包含一段定期启动的javascript(某些setInterval),如果一切顺利,或者如果某些内容被破坏则不包含。该信号定期到达容器框架使其重置超时并且不采取任何其他操作。
如果信号没有到达,当超时到期时,容器会开始定期刷新加载的网页,直到服务器被修复并加载了正确的内容,并向加载器发出信号。
每次触发特定功能时,如何让远程页面向“活动”(例如,设置变量)发信号通知从文件:// URL加载的本地(容器)页面?
答案 0 :(得分:2)
有一个名为porthole的库,基本上可以用SF。的答案来描述,但是以更正式的形式。我刚刚写了一个网页来切换显示两个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 });
};
加上一些额外的控制逻辑。在子网页中,以下是我必须添加的所有内容(以及从控制器调用portholeService.init()
):
// 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.$apply
等,这些网页正在使用AngularJS。
答案 1 :(得分:0)
跨框架,跨站点通信的方法是使用postMessage。
每个正确执行时包含的帧应该执行:
window.top.postMessage('tyrp', '*');
容器文档应包含:
window.onmessage = function(e)
{
if (e.data == 'tyrp') {
//reset timeout here
}
};