Uploading image - data appears like this "���"�!1A"Qaq��2��B�#" and image is blank - Next.js application upload to DigitalOcean Spaces / AWS S3
13:51 05 Mar 2021

I am trying to let my users upload photos in a Next.js application. I set up a remote database and I am writing to the database properly, but the images are appearing blank. I'm thinking it must be a problem with the format of the data coming in.

Here is my code on the front end in React:

async function handleProfileImageUpload(e) {
    const file = e.target.files[0];

    await fetch('/api/image/profileUpload', {
      method: 'POST',
      body: file,
      'Content-Type': 'image/jpg',
    })
     .then(res => {
         console.log('final:', res);
      })
  };

return (
    
    
)

The "file" I declare above (const file = e.target.files[0]) appears like this on console.log(file):

+ --------++-+-++-+------------+----++-+--7--7----7-���"�!1A"Qaq��2��B�#br���$34R����CSst���5����)!1"AQaq23B����
                                                                                                                ?�@��P�n�9?Y�
                                                                                                                             ޞ�p@��zE�  Nk�2iH��l��]/P4��JJ!��(�@�r�Mң[      ���+���PD�HVǵ�f(*znP�>�HRT�!W��\J���$�p(Q�=JF6L�ܧZ�)�z,[�q���   *
�i�A\5*d!%6T���ͦ�@J{6�6��
k@��:JK�bꮘh�A�%=+E      q\���H
q�Q��"�����B(��OЛL��B!Le6���(�� aY
                                  �*zOV,8E�2��IC�H��*)@4է4.�ɬ(�<5��j!§eR27��
��s����IdR���V�u=�u2a��

... and so on. It's long.

I am uploading to Digital Ocean's Spaces object storage, which interfaces with AWS S3. Again, my application is written in Next.js and I am using a serverless environment.

Here is the API route I am sending it to ('/api/image/profileUpload.js'):

import AWS from 'aws-sdk';

export default async function handler(req, res) {

  // get the image data
  let image = req.body;

  // create S3 instance with credentials
  const s3 = new AWS.S3({
    endpoint: new AWS.Endpoint('nyc3.digitaloceanspaces.com'),
    accessKeyId: process.env.SPACES_KEY,
    secretAccessKey: process.env.SPACES_SECRET,
    region: 'nyc3',
  });
  
  // create parameters for upload
  const uploadParams = {
    Bucket: 'oscarexpert',
    Key: 'asdff',
    Body: image,
    ContentType: "image/jpeg",
    ACL: "public-read",
  };

  // execute upload
  s3.upload(uploadParams, (err, data) => {
    if (err) return console.log('reject', err)
    else return console.log('resolve', data)
  })

  // returning arbitrary object for now
  return res.json({});
};

When I console.log(image), it shows the same garbled string that I posted above, so I know it's getting the same exact data. Maybe this needs to be further parsed?

The code above is directly from a Digital Ocean tutorial but catered to my environment. I am taking note of the "Body" parameter, which is where the garbled string is being passed in.

What I've tried:

  • Stringifying the "image" before passing it to the Body param
  • Using multer-s3 to process the request on the backend
  • Requesting through Postman (the image comes in with the exact same garbled format)
amazon-s3 image-processing file-upload next.js