CORS Error on uploading image/video file to google cloud in react js

When user drag and drop the Image, I need to call a method of the server to get the Media_id for that particluar image/video, in the response of that I am getting this ->

MAIN RESPONSE –>>

{
"status": 1, 
"media": {"media_id": 27, "media_type": 1, "media_file_name": "a9989aafcdf1482d8a0967a81b54b476_80a2d60394f15063bef4e44e1a4d83f3.png", "media_placeholder": null, "media_ext": "png"}, 
"upload": 
{
"upload_url": "https://storage.googleapis.com/fnc-59aa2e6b-71552c9d-6441d628-951a8f6f/l.img/ori/a9989aafcdf1482d8a0967a81b54b476_80a2d60394f15063bef4e44e1a4d83f3.png?Expires=1603388214&GoogleAccessId=12345678-compute%40developer.gserviceaccount.com&Signature=UNt8nS3%2BJYiS4AuYdZ7Z2fvfDZ0fAKf8bSZbeRlHyhqxb5i6xjpqnqgR7JYp9Q3FgJItcYr%2BHDL90WiUpbMQi%2B4s0XNW683CaSoUChkRMjj1AvkH%2Be0u8%2Fw5VVIMF9j52bTFePWISTLvwQ1RlEdNPNkrpbcamTsJFyBVi89%2BIpXArsVlhvDzK55Zvj%2Fvzh00GgdNrH%2BRog8Q%2BkGITE8bW%2FxRpQ30OdMZLjpLtp%2FNg5KVotHrx6Bet7vidKymiJQ9BbwCxTRGzBdAITr2rsKTMGZJzfvEKnIczsoiY91Zmc3hjGzUD9OxHGR%2BiRdN%2F2FbotOIVR48RE%2BoAdIGIEfKlw%3D%3D",
"file_name": "a9989aafcdf1482d8a0967a81b54b476_80a2d60394f15063bef4e44e1a4d83f3.png",
"content_type": "image/png", "exp": "2020-10-22 17:36:54.447484"
}}

So, I need to hit this upload url which is coming from the response.Below is my file where I am hitting this as soon as user drop the image ->

UploadImage.js

await this.props.getFirstMediaId(postdata).then(res => {
                    if (res.value && res.value.status === 1) {
                        let media_idArr = this.state.media_id.concat(res.value.media.media_id)
                        this.setState({ media_id: media_idArr, mediaUrl: res.value.upload })
                        customStatus = 'done';
                    }
                }) //First call to the server to get Media_id and the cloud **upload URL**
    
              ***** FOR THIS API RESPONSE, PLEASE SEE THE ABOVE MAIN RESPONSE *****

 const getUploadParams = () => {
            console.log(this.state.mediaUrl, ' -->>> this.state.mediaUrl')
            if (this.state.mediaUrl !== null) {
                console.log(' in get upload param.')
                return this.props.postImageToCloud(this.state.mediaUrl).then(res => {
                    console.log(res, '===>> here is cloud res.')
                })
                    .catch(err => {
                        console.log(' here is error cloud -->>> ', err)
                    })
            }
        }

Below is the file where the method actually call API ->

service.js

export const getFirstMediaId = (data) => {
    return {
        type: GET_FIRST_LISTING_MEDIA,
        async payload() {
            let response = await callAxios.post(SUBMIT_LISTING_FIRST_MEDIA, data);
            return objectPath.get(response, 'data', []);
        }
    }
}

export const postImageToCloud = (url) => {
    return {
        type: PUT_MEDIA_TO_CLOUD,
        async payload() {
            let response = await axios.put(url.upload_url, {}, {
                headers: {
                    'Content-Type': `${url.content_type}`
                }
            })
            return objectPath.get(response, 'data', []);
        }
    }
}

So, the first call is success and I got the above MAIN RESPONSE but as soon as it completes, I call the cloud PUT request and got this CORS error ->

Access to XMLHttpRequest at ‘https://storage.googleapis.com/fnc-59aa2e6b-71552c9d-6441d628-951a8f6f/l.img/ori/a9989aafcdf1482d8a0967a81b54b476_80a2d60394f15063bef4e44e1a4d83f3.png?Expires=1603388214&GoogleAccessId=123456789-compute%40developer.gserviceaccount.com&Signature=UNt8nS3%2BJYiS4AuYdZ7Z2fvfDZ0fAKf8bSZbeRlHyhqxb5i6xjpqnqgR7JYp9Q3FgJItcYr%2BHDL90WiUpbMQi%2B4s0XNW683CaSoUChkRMjj1AvkH%2Be0u8%2Fw5VVIMF9j52bTFePWISTLvwQ1RlEdNPNkrpbcamTsJFyBVi89%2BIpXArsVlhvDzK55Zvj%2Fvzh00GgdNrH%2BRog8Q%2BkGITE8bW%2FxRpQ30OdMZLjpLtp%2FNg5KVotHrx6Bet7vidKymiJQ9BbwCxTRGzBdAITr2rsKTMGZJzfvEKnIczsoiY91Zmc3hjGzUD9OxHGR%2BiRdN%2F2FbotOIVR48RE%2BoAdIGIEfKlw%3D%3D’ from origin ‘http://localhost:8000’ has been blocked by CORS policy: Response to preflight request doesn’t pass access control check: No ‘Access-Control-Allow-Origin’ header is present on the requested resource.

Please suggest me anything for make it working. Thanks.

Answer

Finally after lot of efforts I came to know that I have to pass the file in the body of PUT request, here ->

 let response = await axios.put(url.upload_url, { **file here** }, {
                headers: {
                    'Content-Type': `${url.content_type}`
                }
            })

But I tried passing the image file object simple the html file object using formData and passing as it is, still getting the same error. Then i started using react-dropzone and converted the image file into the string buffer as one of the example in React-dropzone. I am going to paste here that example maybe it can help anyone. See below ->

import React, {useCallback} from 'react'
import {useDropzone} from 'react-dropzone'

function MyDropzone() {
  const onDrop = useCallback((acceptedFiles) => {
    acceptedFiles.forEach((file) => {
      const reader = new FileReader()

      reader.onabort = () => console.log('file reading was aborted')
      reader.onerror = () => console.log('file reading has failed')
      reader.onload = () => {
      // Do whatever you want with the file contents
        const binaryStr = reader.result
        console.log(binaryStr)

      *****PASS THIS (binaryStr) AS IN THE BODY OF PUT TO AXIOS****
    
      }
      reader.readAsArrayBuffer(file)
    })
    
  }, [])
  const {getRootProps, getInputProps} = useDropzone({onDrop})

  return (
    <div {...getRootProps()}>
      <input {...getInputProps()} />
      <p>Drag 'n' drop some files here, or click to select files</p>
    </div>
  )
}

This is one of the Official examples of React-Dropzone, So I just pass that string buffer obj and finally It worked, no CORS issue nothing.

Leave a Reply

Your email address will not be published. Required fields are marked *