I am trying to upload files from Next js 13 application to azure blob storage
I think my file is an object and it expects a blob or buffer, I tried doing that but not of much help either.
my component code
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
"use client";
import { Button } from "@/components/ui/button";
import {
Dialog,
DialogContent,
DialogDescription,
DialogFooter,
DialogHeader,
DialogTitle,
DialogTrigger,
} from "@/components/ui/dialog";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import { useToast } from "@/components/ui/use-toast";
import { DialogClose } from "@radix-ui/react-dialog";
import { useState } from "react";
import { ButtonLoading } from "../LoadingButton";
import axios from 'axios';
export default function UploadData() {
const [file, setFile] = useState<File | null>(null);
const [isLoading, setIsLoading] = useState(false);
const { toast } = useToast();
const handleUrlInput = (event: React.ChangeEvent<HTMLInputElement>) => {
const selectedFile = event.target.files?.[0]
if (selectedFile) {
setFile(selectedFile);
}
};
const handleSubmit = async () => {
const formData = new FormData();
if (file) {
formData.append('file', file);
}
console.log(formData)
const response = axios.post('/api/ingest', formData, {
headers: {
'Content-Type': 'multipart/form-data',
},
})
// Handle the response
if ((await response).status === 200) {
// File uploaded successfully
console.log('File uploaded successfully!');
} else {
// Something went wrong
console.log('Error uploading file:', response);
}
}
return (
<Dialog>
<DialogTrigger asChild>
{isLoading ? <ButtonLoading /> : <Button>Upload</Button>}
</DialogTrigger>
<DialogContent className="sm:max-w-[425px]">
<DialogHeader>
<DialogTitle>Edit profile</DialogTitle>
<DialogDescription>
Enter URL which you want to provide as input for retrieving
information.
</DialogDescription>
</DialogHeader>
<div className="grid gap-4 py-4">
<div className="grid grid-cols-4 items-center gap-4">
<Label htmlFor="name">URL</Label>
<Input
id="name"
type="file"
onChange={handleUrlInput}
className="col-span-full"
/>
</div>
</div>
<DialogFooter>
<DialogClose asChild>
<Button
type="submit"
onClick={handleSubmit}
>
Submit
</Button>
</DialogClose>
</DialogFooter>
</DialogContent>
</Dialog>
);
}
My API code
export async function POST(request: Request, res: Response) {
try {
// const file = (await request.formData())?.get("file") as Blob;
const formData = await request.formData();
const filePart = formData.get("file");
console.log("filePart", typeof filePart);
if (filePart instanceof Blob) {
const fileName = filePart.name;
const buffer = Buffer.from(await filePart.arrayBuffer());
console.log("File Name:", fileName);
console.log("Buffer:", buffer);
const blobClient = containerClient.getBlockBlobClient(fileName);
await blobClient.uploadData(buffer);
return NextResponse.json(res);
} else {
console.log("Invalid file format");
return NextResponse.error();
}
} catch (e) {
console.log(e);
return NextResponse.error();
}
}
I am not able to upload files, the error displayed is Invalid file format:
⨯ RangeError [ERR_HTTP_INVALID_STATUS_CODE]: Invalid status code: 0
According to this SO-thread by Gaurav Mantri, Azure blob storage doesn't support the
multipart/form-data
content type.To upload multiple files you can use
application/octet-stream
or if you need to upload an image you can use the content-type=image/jpeg
Here is a sample code that I tried to upload images to Azure blob storage using the next.js app.
Code:
azconnect.js
Components:
Browser:
Portal:
Here is my GitHub link of the entire project to upload a sample image file to Azure blob storage using next.js.