从获取的图像创建数据 url

Ale*_*502 1 html javascript base64 image data-uri

长话短说

我正在尝试将fetch图像转换为 base64,并将数据 urlimg放入的属性中src,但它不起作用:

async function ajax(id) {
  const tag = document.getElementById(id);
  const path = tag.getAttribute("data-src");
  const response = await fetch(path);
  const blob = await response.blob();
  const base64 = window.btoa(blob);
  const content = `data:image/jpeg;base64,${base64}`;
  tag.setAttribute("src", content);
}
Run Code Online (Sandbox Code Playgroud)

详细信息以及其他一些有效的方法如下


我一直在尝试不同的延迟加载方法:

$ mkdir lazy
$ cd lazy
$ wget https://upload.wikimedia.org/wikipedia/commons/7/7a/Lone_Ranger_and_Silver_1956.jpg # any other example image
Run Code Online (Sandbox Code Playgroud)

现在创建一个名为index.html以下内​​容的文件:

<script>
  // this works
  function setAttribute(id) {
    const tag = document.getElementById(id);
    const path = tag.getAttribute("data-src");
    tag.setAttribute("src", path);
  }

  // this doesn't work for some reason
  async function ajax(id) {
    const tag = document.getElementById(id);
    const path = tag.getAttribute("data-src");
    const response = await fetch(path);
    const blob = await response.blob();
    const base64 = window.btoa(blob);
    const content = `data:image/jpeg;base64,${base64}`;
    tag.setAttribute("src", content);
  }

  // this works too
  async function works(id) {
    const tag = document.getElementById(id);
    const path = tag.getAttribute("data-src");
    const response = await fetch(path);
    const blob = await response.blob();
    const content = URL.createObjectURL(blob);
    tag.setAttribute("src", content);
  }

</script>
<a href="javascript: setAttribute('example');">set attribute</a><br />
<a href="javascript: ajax('example');">data url</a><br />
<a href="javascript: works('example');">object url</a><br />
<img id="example" data-src="Lone_Ranger_and_Silver_1956.jpg"></img><br />
Run Code Online (Sandbox Code Playgroud)

并在该文件夹中启动服务器:

$ python -m SimpleHTTPServer # or whichever local webserver
Run Code Online (Sandbox Code Playgroud)

然后当我在 chrome 中查看它时,我得到了这个:

在此输入图像描述

第一个和第三个链接都有效:

在此输入图像描述

然而,中间的链接并没有:

在此输入图像描述

以下是三个链接分别对标签执行的操作:

作品:

<img id="example" data-src="Lone_Ranger_and_Silver_1956.jpg" src="Lone_Ranger_and_Silver_1956.jpg">
Run Code Online (Sandbox Code Playgroud)

不起作用:

<img id="example" data-src="Lone_Ranger_and_Silver_1956.jpg" src="data:image/jpeg;base64,W29iamVjdCBCbG9iXQ==">
Run Code Online (Sandbox Code Playgroud)

作品:

<img id="example" data-src="Lone_Ranger_and_Silver_1956.jpg" src="blob:http://localhost:8000/736a9e18-c30d-4e39-ac2e-b5246105c178">
Run Code Online (Sandbox Code Playgroud)

非工作示例中的数据 url 看起来也太短了。那么我做错了什么?

Ale*_*502 5

感谢您的建议@dolpsdw。 window.btoa没有做我想的那样。如果有人尝试做同样的事情,将 blob 读入数据 url 的说明如下: https: //stackoverflow.com/a/18650249/5203563

我创建了这个适合我的程序的包装器,如下所示:

(它甚至会为您添加该data:image/jpeg;base64,部分并从 blob 中计算出 mime 类型)


  function readBlob(b) {
    return new Promise(function(resolve, reject) {
      const reader = new FileReader();

      reader.onloadend = function() {
        resolve(reader.result);
      };

      // TODO: hook up reject to reader.onerror somehow and try it

      reader.readAsDataURL(b);
    });
  }

  async function ajax(id) {
    const tag = document.getElementById(id);
    const path = tag.getAttribute("data-src");
    const response = await fetch(path);
    const blob = await response.blob();
    // const base64 = window.btoa(blob);
    // const content = `data:image/jpeg;base64,${base64}`;
    const content = await readBlob(blob);
    tag.setAttribute("src", content);
  }
Run Code Online (Sandbox Code Playgroud)

这给了我我期望的更长的数据网址:

在此输入图像描述