Next.js & Ant Design Dragger: File upload fails on deployed instance

Viewed 2268

I'm trying to build a file upload with Next.js and Ant Design using React.

On localhost, everything works fine. When I deployed the instance and try to upload a file, I get the following error:

Request URL: https://my-app.my-team.now.sh/url/for/test/
Request Method: POST
Status Code: 405 
Remote Address: 34.65.228.161:443
Referrer Policy: no-referrer-when-downgrade

The UI that I use looks like the following:

<Dragger {...fileUploadProps}>{renderImageUploadText()}</Dragger>

where fileUploadProps are:

const fileUploadProps = {
  name: 'file',
  multiple: false,
  showUploadList: false,
  accept: 'image/png,image/gif,image/jpeg',
  onChange(info) {
    const { status } = info.file;
    if (status === 'done') {
      if (info.file.size > 2000000) {
        setUploadSizeError('File size is too large');
      } else {
        handleFieldValue(API_FORM_FIELDS.PICTURE, info);
      }
    } else if (status === 'error') {
      setUploadSizeError(`${info.file.name} file upload failed.`);
    }
  },
};

I assume, it has to do with the server side rendering of Next.js? On the other hand, it might not, because by the time I navigated to url/for/test it should render on the client.

How do you implemented file uploads with Ant Design and Next.js?

3 Answers

Got this to work by passing the prop action="https://www.mocky.io/v2/5cc8019d300000980a055e76" to the <Upload/> component.

The ANTD Upload component must make a POST request to upload the file. It either makes that POST request to the current url, which results in the 405, or to the url specified by the action prop. https://www.mocky.io/v2/5cc8019d300000980a055e76 works as this url.

Inspired by Trey's answer (and because I didn't want to send data anywhere outside my domain) I made a no-op api route that simply returns a success, and then pointed Ant Design <Upload>'s action to /api/noop

/* pages/api/noop.tsx */

import { NextApiRequest, NextApiResponse } from 'next'

export default async function handler(
  req: NextApiRequest,
  res: NextApiResponse
) {
  res.status(200).end('noop')
}

/* Wherever I'm using <Upload /> */

<Upload
  ...otherProps
  action={'/api/noop'}
>

Note: this is specific to Next.js, which makes it easy to create API routes.

This works for me.

By default, the ANTD upload component makes a POST request to upload the file. So, to avoid this, add a customRequest props on Upload as below.

customRequest={({ onSuccess }) => setTimeout(() => { onSuccess("ok", null); }, 0) }
Related