从Javascript加载图像作为base64调用

时间:2018-02-20 13:13:28

标签: javascript ajax django

我正在尝试通过django网络服务器实现小型照片展示。您可以在下面找到将图片加载到图像数组中并每x毫秒更改图像的javascript代码。如果我只从我的django服务器加载一张图片(没有循环),但它停止使用任何类型的循环,它的工作原理。

我很想知道为什么它不能以这种方式工作,并且非常乐意接收有关代码改进的其他反馈。我还不熟悉ajax调用。

此外:Django模板引擎提供了一种简化模板中使用的网址的简便方法。有没有办法在.js文件中使用{{% url %}}标签?

window.images = [];
window.current = 0;
window.imageCount = 2;


function loadImages(){
    for(var i = 0; i < window.imageCount; i++){
        loadNextImage(i);
    }
    showImage();
}

function loadNextImage(i) {
    // https://wiki.selfhtml.org/wiki/JavaScript/XMLHttpRequest/
    var xmlhttp = new XMLHttpRequest();
    xmlhttp.onreadystatechange = function() {
        if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
            window.images.push("data:image/jpeg;base64," + xmlhttp.responseText);
        }
    };
    xmlhttp.open('GET', "http://127.0.0.1:8000/mirror/"+i);
    xmlhttp.send(null);
}

function showImage() {
    if(window.current >= window.imageCount){
        window.current = 0;
    }
    alert("current window count = "+ window.current);
    document.getElementById('imgshow').src = window.images[window.current];
    window.current = window.current + 1;
    setTimeout(showImage, 50000);
}

1 个答案:

答案 0 :(得分:2)

您遇到的直接问题是因为XMLHttpRequest 异步并且您正在处理竞争条件。以下是您的代码正在执行的操作:

  1. 开始循环并告诉浏览器排队XMLHttpRequests
  2. 执行showImage方法(即使我们不知道上面的2个AJAX请求是否已经返回。)
  3. 此行引发异常:document.getElementById('imgshow').src = window.images[window.current];因为window.images为空。
  4. 由于第3步的例外,
  5. setTimeout(showImage, 50000);永远不会被执行。
  6. setTimeout移到document.getElementById('imgshow').src = window.images[window.current];行之上可能会有效。但是,这个是一个坏主意。

    一种解决方案是完全删除循环,并延迟加载图像(仅在需要时加载它们),如下所示:

    window.images = [];
    window.current = 0;
    window.imageCount = 2;
    
    function loadNextImage(i, callback) {
        // https://wiki.selfhtml.org/wiki/JavaScript/XMLHttpRequest/
        var xmlhttp = new XMLHttpRequest();
        xmlhttp.onreadystatechange = function() {
            if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
                window.images.push("data:image/jpeg;base64," + xmlhttp.responseText);
                callback.call();
            }
        };
        xmlhttp.open('GET', "http://127.0.0.1:8000/mirror/"+i);
        xmlhttp.send(null);
    }
    
    // Increments the image counter and loads the image if needed.
    function stepImage() {
        // If we have reached the end of the images, restart.
        if(window.current >= window.imageCount){
            window.current = 0;
        }    
        // Make sure that the image is loaded in the images array,
        // if not, load the image, then show it.
        if(window.images.length <= window.current) {
            loadNextImage(window.current, showImage);
        }    
        // If it's already loaded, just show it.
        else showImage();
    }
    
    // Displays an image onto the page.
    function showImage() {
      document.getElementById('imgshow').src = window.images[window.current];
      // The counter is not incremented until the image is shown!
      window.current++;
    }
    
    // Set a timer to render future images.
    setInterval(stepImage, 3000);
    
    // Render the first image.
    stepImage();
    <img id="imgshow" />