javascript - 使用来自 ajax 数据 URI 请求的原始图像数据

标签 javascript ajax image base64

我正在尝试结合使用 Ajax 和数据 URI 来加载 JPEG 图像并通过单个 HTTP 请求提取其 EXIF 数据。我正在修改一个库( https://github.com/kennydude/photosphere )来做到这一点;目前这个库使用两个 HTTP 请求来设置图像的来源和获取 EXIF 数据。

获取 EXIF 没问题。但是,我在使用来自 ajax 请求的原始数据作为图像源时遇到困难。

技术小测试的源代码:

<!DOCTYPE html>
<html>
<head>
<script type='text/javascript'>

function init()
{
    // own ajax library - using it to request a test jpg image
    new Ajax().sendRequest
    (
        "/images/photos/badger.jpg",
         { method : "GET",
            callback: function(xmlHTTP)
            {

                var encoded = btoa (unescape(encodeURIComponent(xmlHTTP.responseText)));
                var dataURL="data:image/jpeg;base64,"+encoded;

                document.getElementById("image").src = dataURL;
            }
        }
    );
}

</script>
<script type="text/javascript" src="http://www.free-map.org.uk/0.6/js/lib/Ajax.js"></script>
</head>
<body onload='init()'>
<img id="image" alt="data url loaded image" />
</body>
</html>

我得到了看起来像是发回的合理 jpeg 数据,原始数据的长度(以字节为单位)和 base64 编码然后未编码的原始数据是相同的。但是,在 Firefox (25) 和 Chrome (31)(当前版本)上设置图像 src 的尝试都失败了 - chrome 显示“损坏的图像”图标,表明 src 格式无效。

我使用这个 mozilla 页面来获取有关 base64 编码/解码的信息:

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Base64_encoding_and_decoding

知道哪里出了问题吗?环顾四周,我可以创建 base64 编码的图像服务器端,但它可以像这样在客户端完成吗?一方面,base64 编码服务器端明显增加了数据大小,本练习的全部目的是减少从服务器传输的数据量以及请求的数量。

谢谢, 尼克

最佳答案

谢谢。我对此做了更多的挖掘,结果证明至少在当前版本的 Firefox 和 Chrome 上有一个解决方案(编辑:IE10 也可以)。您可以使用 XMLHttpRequest2 并使用类型化数组 (Uint8Array)。以下代码有效:

<!DOCTYPE html>
<html>
<head>
<script type='text/javascript'>

function init()
{
    var xmlHTTP = new XMLHttpRequest();
    xmlHTTP.open('GET','/images/photos/badger.jpg',true);

    // Must include this line - specifies the response type we want
    xmlHTTP.responseType = 'arraybuffer';

    xmlHTTP.onload = function(e)
    {

        var arr = new Uint8Array(this.response);


        // Convert the int array to a binary string
        // We have to use apply() as we are converting an *array*
        // and String.fromCharCode() takes one or more single values, not
        // an array.
        var raw = String.fromCharCode.apply(null,arr);

        // This works!!!
        var b64=btoa(raw);
        var dataURL="data:image/jpeg;base64,"+b64;
        document.getElementById("image").src = dataURL;
    };

    xmlHTTP.send();
}

</script>
</head>
<body onload='init()'>
<img id="image" alt="data url loaded image" />
</body>
</html>

基本上您要求一个二进制响应,然后在将数据转换回(二进制友好的)字符串 String.fromCharCode() 之前创建数据的 8 位无符号整数 View 。 apply 是必需的,因为 String.fromCharCode() 不接受数组参数。然后你使用 btoa(),创建你的数据 url 然后它就可以工作了。

以下资源对此很有用:

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Typed_arrays?redirectlocale=en-US&redirectslug=JavaScript%2FTyped_arrays

http://www.html5rocks.com/en/tutorials/file/xhr2/

尼克

关于javascript - 使用来自 ajax 数据 URI 请求的原始图像数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20035615/

相关文章:

javascript - 如果窗口已经加载,window.stop() 会执行任何操作吗?

javascript - 无法设置 null 的属性 'onclick'

javascript - 在函数调用中的什么时候,AJAX 请求实际上是由浏览器发起的?

javascript - 如何允许下载以二进制数据形式从 AJAX 返回的文件

php - 调用与 javascript 函数位于不同文件中的 php 函数来从数据库检索数据

javascript - 使用 jquery 获取滚动位置

javascript - Ajax/iFrame/FileSystemObject 上传

ios - Base64Encoding 已弃用 : first deprecated in iOS 7. 0

html - CSS图像调整大小问题

java - 将图片保存到变量中