38

我有三台电脑;Server,ClientViewer. 我控制着服务器和查看器。 工作流程

  1. Client连接到 的用户会看到Server一个网页。
  2. 用户通过 php 脚本上传图像。
  3. 该图像嵌入在一些 html 中。
  4. Viewer是一台完全没有用户交互的计算机——没有键盘。Viewer始终运行网络浏览器,显示图片页面。

我现在的问题是,即使服务器磁盘上的图片发生了变化,网页也没有更新。如何在查看器或网页的一部分上刷新 Web 浏览器?

我知道 html、css、javascript、php 和 ajax,但显然还不够好。

4

10 回答 10

60

至少有三种方法可以做到这一点。

纯 HTML

正如Amitd的评论所指出的,在“show.html”中将以下<meta>标签添加到您的文档<head>元素中:

<meta http-equiv="refresh" content="5" />

这将每 5 秒自动刷新一次页面。将属性的值调整为content所需的秒数。

纯 JavaScript:

正如MeNoMore所指出的,document.location.reload()当你调用它时会刷新页面。

<script type="text/javascript">
    //put this somewhere in "show.html"
    //using window onload event to run function
    //so function runs after all content has been loaded.
    //After refresh this entire script will run again.
    window.onload = function () {
        'use strict';
        var millisecondsBeforeRefresh = 5000; //Adjust time here
        window.setTimeout(function () {
            //refresh the entire document
            document.location.reload();
        }, millisecondsBeforeRefresh);
    };
</script>

正如tpower所指出的,可以使用 AJAX 请求,但是您需要编写一个 Web 服务来返回一个指向所需图像的 url。执行 AJAX 请求的 JavaScript 看起来像这样:

<script type="text/javascript">
    //put this somewhere in "show.html"
    //using window onload event to run function
    //so function runs after all content has been loaded.
    window.onload = function () {
        'use strict';
        var xhr,
            millisecondsBeforeNewImg = 5000;    // Adjust time here
        if (window.XMLHttpRequest) {
            // Mozilla, Safari, ...
            xhr = new XMLHttpRequest();
        } else if (window.ActiveXObject) {
            // IE
            try {
                // try the newer ActiveXObject
                xhr = new ActiveXObject("Msxml2.XMLHTTP");
            } catch (e) {
                try {
                    // newer failed, try the older one
                    xhr = new ActiveXObject("Microsoft.XMLHTTP");
                } catch (e) {
                    // log error to browser console
                    console.log(e);
                }
            }
        }
        if (!xhr) {
            // log error to browser console
            console.log('Giving up :( Cannot create an XMLHTTP instance');
        }
        xhr.onreadystatechange = function () {
            var img;
            // process the server response
            if (xhr.readyState === 4) {
                // everything is good, the response is received
                if (xhr.status === 200) {
                    // perfect!
                    // assuming the responseText contains the new url to the image...
                    // get the img
                    img = document.getElementById('theImgId');
                    //set the new src
                    img.src = xhr.responseText;
                } else {
                    // there was a problem with the request,
                    // for example the response may contain a 404 (Not Found)
                    // or 500 (Internal Server Error) response code
                    console.log(xhr.status);
                }
            } else {
                // still not ready
                // could do something here, but it's not necessary
                // included strictly for example purposes
            }
        };
        // Using setInterval to run every X milliseconds
        window.setInterval(function () {
            xhr.open('GET', 'http://www.myDomain.com/someServiceToReturnURLtoDesiredImage', true);
            xhr.send(null);
        }, millisecondsBeforeNewImg)
    };
</script>

其他方法:

最后,要回答您对tpower的回答的问题...$.ajax()正在使用jQuery进行 AJAX 调用。jQuery 是一个 JavaScript 库,它使 AJAX 调用和 DOM 操作变得更加简单。要使用 jQuery 库,您需要在<head>元素中包含对它的引用(以版本 1.4.2 为例):

<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script>

您也可以下载“jquery.min.js”并将其托管在本地,但这当然只会更改您从中加载脚本的 url。

上面的 AJAX 函数在使用 jQuery 编写时看起来更像这样:

<script type="text/javascript">
    //put this somewhere in "show.html"
    //document.ready takes the place of window.onload
    $(document).ready(function () {
        'use strict';
        var millisecondsBeforeNewImg = 5000;    // Adjust time here
        window.setInterval(function () {
            $.ajax({
                "url": "http://www.myDomain.com/someServiceToReturnURLtoDesiredImage",
                "error": function (jqXHR, textStatus, errorThrown) {
                    // log error to browser console
                    console.log(textStatus + ': ' + errorThrown);
                },
                "success": function (data, textStatus, jqXHR) {
                    //get the img and assign the new src
                    $('#theImgId').attr('src', data);
                }
            });
        }, millisecondsBeforeNewImg);
    });
</script>

我希望很明显,jQuery 版本更简单、更干净。但是,鉴于您的项目范围很小,我不知道您是否愿意为 jQuery 的额外开销而烦恼(并不是说那么多)。我也不知道您的项目要求是否允许使用 jQuery。我包括这个例子只是为了回答你的问题$.ajax()

我同样确信还有其他方法可以完成刷新图像。就个人而言,如果图像 url 总是在变化,我会使用 AJAX 路由。如果图像 url 是静态的,我可能会使用<meta>刷新标签。

于 2013-01-12T05:59:23.790 回答
21

我有完全相同的应用程序。只需使用WebSockets.

您可以启动 a ,服务器将在收到更新时websocket connection通知它。Viewer您可以通过 websocket 发送更新的图像,完全异步,不会干扰显示或用户交互。

如果您使用计时器,您将无法获得快速更新,或者您将不断刷新页面而不使用。


细节:

将需要一个 Websocket 服务器,如pywebsocketor phpwebsocket

客户:

需要 HTML5 websocket 支持,当前所有浏览器都支持。

发生图像更新时需要注册消息。这就像注册一个回调。

例子:

wSocket = new WebSocket('ws://' + serverIP + ':' + serverPort + '/images');

wSocket.onopen = function() {
    console.log("Primary Socket Connected.");

    connectedPrimary = true;

    wSocket.send("sendImageUpdates");
};

wSocket.onmessage = function(evt) {
    // evt is the message from server

    // image will be representated as a 64 encoded string

    // change image with new one
    $("#image").attr('src', 'data:image/png;base64,' + evt.data);
}

wSocket.onclose = function() {
    console.log("Primary Socket Closed.");

    wSocket = null;
};

wSocket.onerror = function(evt) {
    alert(evt);
}

每当服务器发送更新时,将调用映射到的函数wSocket.onmessage,您可以对它做任何您需要做的事情。

服务器:

将侦听来自客户端的连接(可以支持多个客户端)。一旦建立连接并"sendImageUpdates"收到消息,服务器将等待图像中的任何更新。当上传新图像时,服务器将创建一条新消息并发送给客户端。

优点

  1. 将在图像上传后立即获得更新,并且仅在图像上传时。
  2. 客户将知道图像已更改并可以执行其他功能。
  3. 完全异步和服务器驱动。
于 2013-01-16T07:51:36.910 回答
11

您可以使用 AJAX 请求来提供帮助。例如,您正在做的是每五秒钟轮询一次服务器以获取图像。相反,您可以轮询服务器以获取新的图像 ID,并使用该 ID 而不是图像源的随机数。在这种情况下, src 属性只会在有新图像时更改/重新加载。

<script language="JavaScript"><!--
function refreshIt() {
   if (!document.images) return;
   $.ajax({
      url: 'latest-image-id.json',
      success: function(newId){
          document.images['doc'].src = 'doc.png?' + newId;        
      }
   });
   setTimeout(refreshIt, 5000); // refresh every 5 secs
}
//--></script>
</head>
<body onLoad=" setTimeout(refreshIt, 5000)">
<img src="doc.png" name="doc">

另一种方法是在图像通过 Web 套接字更改时从服务器获取通知。

于 2012-11-14T09:29:51.747 回答
5

在特定的时间间隔内重新加载页面可能会奏效。

setTimeout(function(){
window.location.reload(1);
}, 5000);

上面的代码在 5 秒内重新加载当前页面。

或者

您也可以进行异步的 ajax 调用,而且您不必刷新整个页面。签出以下代码:

$.ajax({
  url: "test.aspx",
  context: document.body
}).done(function() {
  $(this).addClass("done");
});

这可以用来代替 window.location.reload(1);

[**test.html:**此页面必须在加载时将所有图像 src 引入其中,即,将图像引入页面的服务。]

执行此操作后,您将获得可以分配给当前页面中的 html 元素的data结果。done(function()例子:

done(function() {
$('#ImageId').attr('src', data);
 });

这会将 img 标签的 src 设置为data来自 test.aspx

优点:不刷新整个页面,只添加新图像。

浏览此链接以了解有关 jQuery Ajax 的更多信息...

于 2013-01-16T07:43:50.073 回答
4

采用。

document.location.reload();

例如对按钮单击做出反应:

<input type="button" value="Reload Page" onClick="window.location.reload()">
于 2012-11-14T09:28:24.670 回答
1

如果您的浏览器支持 websocket,您需要实现与服务器的客户端长轮询连接,即所谓的 COMET 或使用套接字。

于 2013-01-12T13:41:56.700 回答
1

在 javascript 中,有几种以编程方式刷新的方法。

首选方法是location.reload()

另一种方法是通过设置location.href属性,浏览器自动转到新的 url,所以location=location或者location.href=location.href也会这样做。

虽然第二种方法可能看起来很奇怪。

回顾一下,那就是:

location.reload();
//or
location.href=location.href;
//or
location=location;


我希望这会有所帮助。

于 2013-01-14T23:54:47.637 回答
1

最简单的是使用 AJAX 池。
为此,在处理上传的 php 文件中,当上传新照片时,在文件中保存一个 unix 时间戳:

file_put_contents('lastupload.txt', strval(time())); // Save timestamp of upload

创建另一个 php 文件(例如:polling.php)来处理 AJAX 调用并返回上次上传的 unix 时间戳:

echo file_get_contents('lastupload.txt'); // Send last upload timestamp

在 Viewer javascript 代码中进行 AJAX 轮询,它将检测时间戳的变化并在需要时刷新图像:

$(function() {
   setInterval(polling, 1000); // Call polling every second.
});
var lastupload = 0;
function polling() {
   $.ajax({
      url: 'polling.php',
      success: function(timestamp){
          if (timestamp > lastupload) { // Is timestamp newer?
              document.images['image'].src = 'image.png?' + timestamp; // Refresh image
              lastupload = timestamp;
          }
      }
   });
}

我还没有测试过代码,所以可能会有错误,但这是我的想法。

于 2013-01-16T16:33:35.910 回答
1

我认为您不需要为此编写大量脚本。我解决了这个问题,只是在图片网址之后添加了一个问号和随机数。如果您不更改图像 url,浏览器会从缓存中调用它。

要在页面上显示最新图片:

<img src="<?php echo $image_url; ?>?<?php echo rand(10,99); ?>"/>

它打印如下内容:

http://static.example.com/myimage.jpg?56 

您的问题和我的解决方案是通过在我的问题中使用 Jquery 和 javascript 随机数函数将其更改为随机数来刷新图像 url。我认为您明白了这一点,并会根据您的需要对其进行调整。

$('#crop_image').live('click',function(){
    $(this).html(ajax_load_fb);
    var x = $('#x').val();
    var y = $('#y').val();
    var w = $('#w').val();
    var h = $('#h').val();
    var dataString = 'process=image_crop&x='+x+'&y='+y+'&w='+w+'&h='+h;
    $.ajax({
        type: 'POST',
        url: '<?php echo $siteMain;?>ajax/ajaxupload.php',
        data: dataString,
        cache: false,
        success: function(msg) {
            $('#crop_image').html('Crop Selection');
            $('.crop_success_msg').slideDown('slow');
            var numRand = Math.floor(Math.random()*101);
            $('#current_img').html('<img src="/images/large_<?php echo $user['username'];?>.jpg?'+numRand+'"/>');
        },
        error: function(response, status, error)
        { 
            $(this).html('Try Again');
        }
    });
});
于 2013-01-16T17:39:11.607 回答
0

最好的解决方案是在查看器 Web 浏览器上编写一个小的 php 脚本来定期检查图像,如果图像发生更改,它将重新加载它。由于 php 代码在服务器端运行,因此您可以轻松完成。如果您需要代码片段让我知道,我希望这会有所帮助。

于 2013-01-19T04:08:23.127 回答