Sending a photo to digital ocean via the s3Client

I'm having trouble uploading an image to Digital Ocean Spaces.

Here is my client-side code:

const formData = new FormData();
formData.append('myFile', file as string)
fetch('/api/upload',
        {
        method: 'POST',
        body: formData
        }).then(response => {
            console.log(`response sucess: ${response.status}`)
        }).catch(error => {
            console.log(error)
            // Handle error
});

As for the server-side code (Next.js), I must admit I am a bit confused..

export default async function upload(req: NextApiRequest & { [key: string]: any }, res: NextApiResponse) {
    const multerUpload = multer({ dest: "uploads/" });
    await runMiddleware(req, res, multerUpload.single("file"));
    const file = req.body.myFile;
    const { bucket, key, fileName } = req.body;
    const contentHash = crypto.createHash('sha256').update(file).digest('hex');
    const content_length = getBytesForContentLength(file)
    const bucketParams = {
        Bucket: bucket,
        Key: key,
        Body: file,
        ContentType: getImageType(file),
        ContentLength: content_length, 
        Headers: {
          'X-Amz-Content-SHA256': `hex(${contentHash})`
      }
    };
    try {
        const response = await s3Client.send(new PutObjectCommand(bucketParams));
        console.log(response.$metadata);
        console.log("Success");

        //todo: if successful, post the path to the server DB

        res.status(200)

        
    } catch (err) {
        console.log("Error", err);
        res.status(500).send("Server Error");
    }

The mentioned functions are defined as follows:

function runMiddleware(req: NextApiRequest & {[key: string]: any}, res: NextApiResponse, fn: (...args: any[]) => void): Promise<any> {
    return new Promise((resolve, reject) => {
      fn(req, res, (result: any) => {
        if (result instanceof Error) {
          return reject(result);
        }
  
        return resolve(result);
      });
    });
  }
  
  export const config = {
    api: {
      bodyParser: false,
    },
};

and

function getBytesForContentLength(base64String: string): number {
    // assume that file_str is the base64 encoded file string
    const myBuffer = Buffer.from(base64String, 'base64');
    return myBuffer.byteLength
}

The error message I'm encountering reads as follows:

'$fault': 'client',
  '$metadata': {
    httpStatusCode: 400,
    requestId: '***',
    extendedRequestId: undefined,
    cfId: undefined,
    attempts: 1,
    totalRetryDelay: 0
  },
  Code: 'XAmzContentSHA256Mismatch',
  BucketName: '***',
  RequestId: '***',
  HostId: '***'
}

The XAmzContentSHA256Mismatch error seems persistent despite my attempt to manually set the X-Amz-Content header. Additionally, specifying the ContentLength parameter is crucial to avoid another error related to ContentLength.

Code: 'MissingContentLength',
  BucketName: '***',
  RequestId: '***',
  HostId: '***'

I would greatly appreciate any assistance in resolving these issues.

Answer №1

Here's how I tackled the problem:

The file variable contains a string that is base64 encoded. To work with it, I converted it into a blob and then transformed the blob into an arrayBuffer which was further typecasted to Buffer for processing.

const base64Data = await fetch(file);

const blobData = await base64Data.blob();
const arrayBufferData = await blobData.arrayBuffer()

const uploadParams = {
        Bucket: bucket,
        Key: key,
        Body: arrayBufferData as Buffer,
};

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

mvc and ajax - failing to access model attributes

I'm encountering an issue where the inputs in my beginform are not being auto-posted successfully. Their values do not reach the model or controller and remain null (breakpoints are never hit). What could possibly be causing this? @model project.Mo ...

Mesh normalization in three.js is the process of standardizing the vertices

After loading a mesh from an obj file, I attempted to normalize it. Unfortunately, the results are not what I expected. Below is the code snippet for loading and centering the mesh: const manager = new THREE.LoadingManager(); const loader = new THREE.OBJL ...

Choose a random cell in Jquery every second

I am searching for a method to choose one div out of sixteen and change its CSS backgrounds. This selection needs to occur every second, so a new div is selected from the group each second. I am struggling with implementing the "every second" functionalit ...

The (window).keyup() function fails to trigger after launching a video within an iframe

Here is a code snippet that I am using: $(window).keyup(function(event) { console.log('hello'); }); The above code works perfectly on the page. However, when I try to open a full view in a video iframe from the same page, the ke ...

Utilize utility functions within the onCreated lifecycle event in Meteor

Here is my current setup: Template.myTemplate.helpers({ reactiveVar: new ReactiveVar }); How can I initialize reactiveVar within the onCreated function? Template.restaurantEdit.onCreated(function() { // I want to initialize helpers.reactiveVar here ...

Challenges with AngularJS validation

I'm facing a couple of issues related to validation in AngularJS Problem 1: How can I achieve the following in the controller using AngularJS and not in the view? vanilla js code document.getElementById('InputId').value.length I attempt ...

Ways to resolve the pg-promise error: "Promise library must be specified."

After successfully creating a simple API in ExpressJS with pg-promise to communicate with my PostgreSQL database on Windows, I encountered an issue when attempting to run it on Ubuntu 15.04. The following error message appears when starting the server: / ...

Ways to retrieve the checkbox value using PHP in conjunction with XML

I am currently in the process of learning PHP, XML, AJAX, and other related technologies. I have a form that is working fine for the most part, but I am facing an issue with passing the value/state of a checkbox to my PHP script. It's worth mentionin ...

When a specific condition is met, Jquery can automatically execute a function contained

I am trying to slowly reveal the h1 tag using jQuery for demonstration purposes. The scroll function is working when I manually click to initiate it, but I am having trouble triggering it automatically. I feel like I might be missing something simple and ...

Use the .setAttribute method to assign a value to a variable

Suppose I have the following code snippet: for (var k = 0; k < id_arr.length; k++) { if (k === 0) { sets[k].setAttribute("style", "grid-column: col 1 / span 1; grid-row: row; margin-top: 40px"); } if (k === 1) { sets[k].set ...

How can a parent component be handed over to a child component constructor as an instance?

Trying to wrap my head around the inner workings of the table component in PrimeNG. I'm particularly puzzled by how a parent component instance is passed into the constructor of a child component. Take a look at the code snippet from the TableBody co ...

Creating a constructor in Typescript for a class with customizable properties

Error: Type 'typeof Md' is not assignable to type 'Model'. Type 'Md' is not assignable to type 'Store'. The code snippet defines a generic Store interface and a Model interface in TypeScript. The Model interface requ ...

Guide to incorporating a feature into the dynamically created button using JavaScript?

Within an HTML table displaying product data, I am looking to incorporate a feature that allows users to delete specific products with the click of a button. This button will be dynamically generated alongside the corresponding information in the table thr ...

Is there a way for me to update the placeholder text in my script from "CHANGE ME

Can anyone help me troubleshoot this code that's not working on my computer? I have a paragraph with the text CHANGE ME inside an element with the id "warning". I want to update this text when the login button is clicked, but it doesn't seem to ...

Having trouble initiating a Next.js and Tailwind project using the npm run dev command

After creating a next - tailwind project using npx create-next-app -e with-tailwindcss my-project, I encountered an error while trying to run the app on Windows 7. When running npm run dev, I received the following error message: > @ dev E:\Coding ...

Node.js Express Timer with API for Initializing/Stopping/Reinitializing

I have a functional (though not the most aesthetically pleasing) solution for this problem. My expertise lies mainly in C# and Powershell, so I am relatively new to Node.js & Express. What I am aiming for is a simple webpage at localhost:8080/sw that featu ...

Is it possible for NodeJS to prioritize IPv6 DNS lookups as the default option?

In my work with multiple TypeScript (NodeJS 14) client applications that are all Dockerized, I primarily use axios for most HTTP requests. However, there are other tools used as well. Typically, DNS queries default to resolving IPv4 addresses, resulting i ...

When utilizing react-scripts test, a mock promise resolves to undefined, yet functions properly when executing Jest independently

I'm currently working on creating a basic mock function that will return a promise resolving to a specific value. const mockPromise = jest.fn().mockResolvedValue('example'); test('verifying the resolution of the mock promise', asy ...

Exploring the fundamentals of JavaScript within the context of Express.JS

Can you please explain the distinction between these two blocks of code in JavaScript? app.get("/api/products/1", (req, res) => { const singleProduct = products.find((product) => { product.id === 1; }); res.json(singleProduct); }) ...

React state management challenges

Is there a way to bind API response data to textboxes? <label htmlFor="jobTitle" className="form-label lbl">Job Title:</label> <input type="text" id=" ...