最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - How to fetch and display blob images - Stack Overflow

programmeradmin2浏览0评论

I am trying to save images to indexeddb and then fetch and display them in a react app. My approach is to convert images to a blob and save the blob url to indexeddb and then when it's time to display, fetch the blob url and set the image url as .src.

How I created the blob

fetch(imgurl, {
                mode: 'no-cors',
                method: "get",
                headers: {
                     "Content-Type": "application/json"
                } 
             }) 
            .then(response => response.blob())
            .then(async images => {
               
                    var blob_url = URL.createObjectURL(images)
                  
                    var blobA = blob_url.replace("blob:","") 
                    var blobB = blobA.replace('"','')

I am trying to save images to indexeddb and then fetch and display them in a react app. My approach is to convert images to a blob and save the blob url to indexeddb and then when it's time to display, fetch the blob url and set the image url as .src.

How I created the blob

fetch(imgurl, {
                mode: 'no-cors',
                method: "get",
                headers: {
                     "Content-Type": "application/json"
                } 
             }) 
            .then(response => response.blob())
            .then(async images => {
               
                    var blob_url = URL.createObjectURL(images)
                  
                    var blobA = blob_url.replace("blob:","") 
                    var blobB = blobA.replace('"','')

this is bloburl blob:http://localhost:3000/d7a55f39-b496-476b-8c3c-857874bd107c

I then remove blob: and save this url in indexeddb to be fetched when needed http://localhost:3000/d7a55f39-b496-476b-8c3c-857874bd107c

this is where I need to use the blob image

import React from "react";
import { Row, Col, Container, Image } from 'react-bootstrap';

   
function Item({ item }) { 
    const imgurl = item.productimg
    fetch(imgurl)
        .then(res => res.blob()) // Gets the response and returns it as a blob
        .then(async blob => {
            const test = await blobToImage(blob)  
            console.log("image test",test)
        
            let objectURL = URL.createObjectURL(blob);
           let myImage = document.getElementById('myImg')
           myImage.src = objectURL;
            
        });
       
    return (
        <div className="item" id={item.id}>


            <Row>
                <Col> 
                <Image  id="myImg" width="50" height="58" rounded />

                </Col>
                <Col xs={6}>
                    <div className="item-info">
                        <p>{item.name}</p>
                    </div>
                </Col>
                <Col>3 of 3</Col>
            </Row>
           

            <div className="item-actions">
                <button className="btn-remove">X</button>
            </div>
        </div>
    );
}

export default Item;

Item contains all the productdata including the saved blob url. The problem is the images are not showing and I could not figure out why.

what could i be doing wrong and how can I display the images

Share Improve this question edited Mar 12, 2021 at 17:03 e.iluf asked Mar 12, 2021 at 13:39 e.ilufe.iluf 1,6597 gold badges32 silver badges81 bronze badges
Add a ment  | 

2 Answers 2

Reset to default 7

Don't modify the Blob's URL.

When you took the blob: part out of the URL string to the Blob, the browser no longer knew that you were referencing your Blob. Instead, try leaving the URL alone after creating it with URL.createObjectURL.

On top of that, when synchronizing a ponent with an external resource (like fetching data), you should use React's useEffect hook.

Example with React

You can view this example live at StackBlitz.

function Item({ item }) {
  const imgURL = item.productimg;
  const [blobURL, setBlobURL] = React.useState(null);

  React.useEffect(() => {
    const controller = new AbortController(); // https://developer.mozilla/en-US/docs/Web/API/AbortController
    const signal = controller.signal;
    fetch(imgURL, { signal })
      .then((res) => res.blob()) // Get the response and return it as a blob
      .then((blob) => { // Create a URL to the blob and use it without modifying it.
        setBlobURL(URL.createObjectURL(blob));
      })
      .catch((error) => { // Error handling here
        console.error(error);
      });

    // Cancel the fetch request on any dependency change
    return () => controller.abort();
  }, [imgURL]);

  return (
    <div className="item" id={item.id}>
      <Row>
        <Col>
          {blobURL ? <Image src={blobURL} id="myImg" width="50" height="58" rounded /> : <p>Loading...</p>}
        </Col>
        <Col xs={6}>
          <div className="item-info">
            <p>{item.name}</p>
          </div>
        </Col>
        <Col>3 of 3</Col>
      </Row>

      <div className="item-actions">
        <button className="btn-remove">X</button>
      </div>
    </div>
  );
}

Example with plain JavaScript

const imgURL = "https://cdn62.picsart./182788826000202.jpg?type=webp&to=crop&r=256"
fetch(imgURL)
  .then(response => response.blob())
  .then(blob => {
    document.getElementById('my-img').src = URL.createObjectURL(blob)
  })
<img id="my-img" />

Good Luck...

The URL lifetime is tied to the document in the window on which it was created.. ObjectURL is not meant to be saved somewhere. You can convert your image to base64 and store as data-uri instead.

发布评论

评论列表(0)

  1. 暂无评论