Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Getting a broken image file from Blob storage #546

Closed
agan-k opened this issue Dec 21, 2023 · 3 comments
Closed

Getting a broken image file from Blob storage #546

agan-k opened this issue Dec 21, 2023 · 3 comments

Comments

@agan-k
Copy link

agan-k commented Dec 21, 2023

"next": "^14.0.2",
"@vercel/blob": "^0.16.1"

I am following along with the Next Learn - Dashboard App Router example.
I am extending it by adding "Create Customer" and I'm trying to leverage Blob storage to upload the Avatar image.

Everything works as expected, except, I get a broken image file when referencing from the Database. Downloading the file from Blob also gives me a broken file.

I followed the recommended solution from #407 but it did not work for me.

Screenshot 2023-12-21 at 3 01 27 AM Screenshot 2023-12-21 at 3 05 41 AM

Screenshot 2023-12-21 at 3 05 19 AM

As suggested by @vvo I changed from "request.body" to "request". still same...

// api/avatar/upload/route.js

export async function POST(request) {
  const { searchParams } = new URL(request.url);
  const filename = searchParams.get('filename');
 
  // As suggested by @vvo I changed from "request.body" to "request". still same...
  const blob = await put(filename, request, { 
    access: 'public',
    addRandomSuffix: false,
  });
 
  return NextResponse.json(blob);
}
export const config = {
  api: {
    bodyParser: false,
  },
};

create-form.tsx entire file.
Relevant code:

export default function Form() {
  const inputFileRef = useRef<HTMLInputElement>(null);
  const [blob, setBlob] = useState<PutBlobResult | null>(null);

    async function attachAvatar(event: React.FormEvent<HTMLFormElement>) {
          event.preventDefault();
    
          if (!inputFileRef.current?.files) {
            throw new Error('No file selected');
          }
    
          const file = inputFileRef.current.files[0];
          console.log('here:', file);
    
          const response = await fetch(
            `/api/avatar/upload?filename=${file.name}`,
            {
              method: 'POST',
              body: file,
            },
          );
          const newBlob = (await response.json()) as PutBlobResult;
    
          setBlob(newBlob);
      }

. . . 
@luismeyer
Copy link
Member

luismeyer commented Dec 21, 2023

hey @agan-k,
it might be that Next.js changed some internals how the bodyParser is working, since @vvo recommended his solution. The solution I know from the top of my head is to use FormData for sending the file to your route. This takes advantage of the built-in bodyParser Next.js provides. Your code might look like this:

Client:

const formData = new FormData();
formData.set("filename", file.name);
formData.set("file", file);

const response = await fetch('/api/avatar/upload', {
  method: "POST",
  body: formData,
});

API Route:

const body = await request.formData();

const filename = body.get("filename");
const file = body.get("file");

const blob = await put(filename, file, {
  access: "public",
  addRandomSuffix: false,
});

Docs: https://nextjs.org/docs/app/building-your-application/routing/route-handlers#request-body-formdata
Please let me know if this helps :)

@agan-k
Copy link
Author

agan-k commented Dec 21, 2023

Thanks @luismeyer this worked!

@agan-k agan-k closed this as completed Dec 21, 2023
@danielo515
Copy link

The only thing that worked for me is using the formData method.
I'm using Astro, and instead of "attaching" the file to the new FormData I just guet the form data from the request:

  const formData = await request.formData();
  const file = formData.get("file") as File | null;
// check that file is not null bla bla
  const blob = await put(filename, file, {
    access: "public",
  });

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants