Home > OS >  getting blob from image and sending to server react
getting blob from image and sending to server react

Time:06-09

Learning react by coding, here i want to let user choose an image then user shoul be able to send it as blob, need advice on converting it into blob ?

this is my fetch with post method

 const sendToserver = async () => {
    let pollUrl = `api/...`;

  

    const blob: any = await getImage();
    // SEND THE BLOB TO YOUR SERVER
    try {
      const res = await fetch(pollUrl, {
        method: "POST",
        body: blob,
      });
      const data = await res.text();

      if (res.ok) console.log("SUCCESS", data);
      else throw new Error(data);
    } catch (e) {
      console.error(e);
    }}

my uploader which need advice on how to get blob image of it:

const {useState} = React;

const blobFile= (file) => new Promise((resolve, reject) => {
    const reader = new FileReader();
    reader.onload = (event) => {
      resolve(event.target.result)
    };
    reader.readAsDataURL(file);
    })

const App = () => {
  const [blob, setBlob] = useState('')

  const onChange = (file) => {
    
    if(!file) {
      setBlob('');
      return;
    }

    blobFile(file)
      .then(dataUri => {
        setBlob(dataUri)
      })
    
  }

  return <div>
  <img width="200" height="200" src={blob} alt="avatar"/>
  <input type="file" onChange={(event) => onChange(event.target.files[0] || null)} />
  </div>
}


ReactDOM.render(
    <App/>,
    document.getElementById('root')
  );
<script src="https://unpkg.com/react/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom/umd/react-dom.development.js"></script>
<script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>
<div id="root"></div>

english is not my mother language, so could be mistakes

CodePudding user response:

Unless you want to show this image to the user in the browser right after he sends it, you don't have to convert it to Blob in order to send to server, you can read this file and make a POST directly to your api, so there in your api you can handle this file the way you want, like saving to disk or sending to some cloud service like aws bucket.

Anyway, I will show you both examples, how to convert to Blob and how to send to server.

converting to Blob

const onChange = (file) => {

  if(!file) {
    setBlob('');
    return;
  }
  // just use the URL.createObjectURL to convert to blob
  setBlob(URL.createObjectURL(file))
}

You should pay attention when converting files to Blob because it can leads to issues with memory, so when the Blob is no longer necessary for the user, you can remove it from memory this way:

URL.revokeObjectURL(blob)

sending the file to server

it's almost the same thing you've did before, but with the file directly set in the body

const sendToServer = async (file) => {
  if(!file) return
  try {
    return await fetch('api/...', { method: 'POST', body: file }).then(res => {
      console.log("SUCCESS", res.text())
    })
  } catch(error) {
    console.log(error)
  }
}

const App = () => {

  return <div>
  <img width="200" height="200" src={blob} alt="avatar"/>
  <input type="file" onChange={async (event) => await sendToServer(event.target.files[0] || null)} />
  </div>
}

Update: To use a button to send files you can make the input hidden and use the button to trigger the dialog box from the input, like so:

// I will be using the useRef hook, but you could do it with vanilla javascript as well

import React, { useRef} from 'react'
const App = () => {
  const fileInputRef = useRef(null)

  // this is the function that triggers the dialog box from the input
  const openFileDialog = () => {
    fileInputRef.current?.click()
  }

  return <div>
  <img width="200" height="200" src={blob} alt="avatar"/>
  // add hidden property and the ref to useRef hook
  <input hidden ref={fileInputRef} type="file" onChange={async (event) => await sendToServer(event.target.files[0] || null)} />

  // open the input's dialog on click
  <button onClick={openFileDialog}> Upload file </button>
  </div>
}
  • Related