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

Send multipart/form-data with antd upload #11616

Closed
1 task done
Mohamed-Ghanem opened this issue Aug 5, 2018 · 10 comments
Closed
1 task done

Send multipart/form-data with antd upload #11616

Mohamed-Ghanem opened this issue Aug 5, 2018 · 10 comments
Assignees

Comments

@Mohamed-Ghanem
Copy link

Mohamed-Ghanem commented Aug 5, 2018

  • I have searched the issues of this repository and believe that this is not a duplicate.

Version

3.8.0

Environment

react: 16.4.2, antd: 3.8.0, chrome: 67.0.3396.99

Reproduction link

Edit on CodeSandbox

Steps to reproduce

You can find the code with the issue in this sandbox:
https://codesandbox.io/s/j3q07kyy8w

What is expected?

Request Payload:

------WebKitFormBoundaryysdTGvf0cRZVGpQ4
Content-Disposition: form-data; name="file"; filename="aFileName.zip"
Content-Type: application/octet-stream

[0,1,2]
------WebKitFormBoundaryysdTGvf0cRZVGpQ4
Content-Disposition: form-data; name="x2"

y2
------WebKitFormBoundaryysdTGvf0cRZVGpQ4
Content-Disposition: form-data; name="x3"

true
------WebKitFormBoundaryysdTGvf0cRZVGpQ4
Content-Disposition: form-data; name="x4"

2
------WebKitFormBoundaryysdTGvf0cRZVGpQ4

What is actually happening?

Request Payload:

------WebKitFormBoundaryysdTGvf0cRZVGpQ4
Content-Disposition: form-data; name="file"; filename="aFileName.zip"
Content-Type: application/zip


------WebKitFormBoundaryysdTGvf0cRZVGpQ4

This is the question on stackoverflow:
https://stackoverflow.com/q/51697944/2648837

@yokyj
Copy link

yokyj commented Aug 10, 2018

well you may do it in customRequest

		customRequest: (options: any) => {
			const data= new FormData()
			data.append('file', options.file)
			const config= {
				"headers": {
					"content-type": 'multipart/form-data; boundary=----WebKitFormBoundaryqTqJIxvkWFYqvP5s'
				}
			}
			axios.post(options.action, data, config).then((res: any) => {
				options.onSuccess(res.data, options.file)
			}).catch((err: Error) => {
				console.log(err)
			})
			
		},

@afc163 afc163 closed this as completed Aug 10, 2018
@Mohamed-Ghanem
Copy link
Author

I had to do it that way.
Thanks for your reply.

@raisiqueira
Copy link

hey, i have a some problem.

i have this call

  avatarUpload = file => {
    const userId = this.props.userdetail.data.data.id;
    const data = new FormData();
    data.append('avatar', file);
    const config = {
      headers: {
        'content-type': 'multipart/form-data',
      },
    };
    api
      .post(`${API_VERSION}/users/${userId}/avatar`, data, config)
      .then(res => console.log(res))
      .catch(err => console.log(err));
  };

and i'm using this on action props:

                <Upload
                  name="avatar"
                  action={this.avatarUpload}
                  listType="picture-card"
                  beforeUpload={this.beforeUpload}
                >
                  <p className="ant-upload-drag-icon">
                    <Icon type="inbox" />
                  </p>
                  <p className="ant-upload-text">
                    Clique ou arraste um arquivo.
                  </p>
                </Upload>

But are returning 204, no-content. Someone can help-me?

@yokyj
Copy link

yokyj commented Oct 2, 2018

what do you mean..
It returns 204 because your server writes this way and has nothing to do with your frontEnd code
but there is indeed a problem in your code: action should be a string or a function which returns a promise,yours has nothing to return

@ochive
Copy link

ochive commented May 23, 2019

@yogithesymbian
Copy link

Error
Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: undefined. You likely forgot to export your component from the file it's defined in, or you might have mixed up default and named imports.

@raconstruct
Copy link

Hi @Mohamed-Ghanem The Code sandbox not working Man

@neelduttahere
Copy link

well you may do it in customRequest

		customRequest: (options: any) => {
			const data= new FormData()
			data.append('file', options.file)
			const config= {
				"headers": {
					"content-type": 'multipart/form-data; boundary=----WebKitFormBoundaryqTqJIxvkWFYqvP5s'
				}
			}
			axios.post(options.action, data, config).then((res: any) => {
				options.onSuccess(res.data, options.file)
			}).catch((err: Error) => {
				console.log(err)
			})
			
		},

Any request from this upload component is being registered as an OPTIONS request on my backend server where i need to upload the file. I cannot find cause of this. Do you have any idea?

@davidchoo12
Copy link

Here is my solution for using <Upload> for single file input and have the <Form> submit the file by wrapping <Upload> in <Form.Item> like so:

<Form.Item
  name="avatar"
  label="Upload profile picture"
  getValueFromEvent={({file}) => file.originFileObj}
>
  <Upload
    accept="image/png, image/jpeg"
    maxCount={1}
    listType="picture-card"
    showUploadList={false}
    customRequest={dummyRequest} // to override the component sending request on image upload, see https://stackoverflow.com/a/51519603/4858751
    beforeUpload={beforeUpload} // see https://ant.design/components/upload/#components-upload-demo-avatar
    onChange={handleChange} // see https://ant.design/components/upload/#components-upload-demo-avatar
  >
    {imageUrl ? <img src={imageUrl} alt="avatar" style={{ width: '100%' }} /> : uploadButton}
  </Upload>
</Form.Item>

and the <Form>'s onFinish has to send as multipart/form-data like so:

const onFinish = async values => {
  const formData = new FormData();
  for (const name in values) {
    formData.append(name, values[name]); // there should be values.avatar which is a File object
  }
  const res = await fetch('/blabla', {
    method: 'POST',
    body: formData // automagically sets Content-Type: multipart/form-data header
  });
  // handle res however you want
}

@RKdevFusion
Copy link

Here is my solution for using <Upload> for single file input and have the <Form> submit the file by wrapping <Upload> in <Form.Item> like so:

<Form.Item
  name="avatar"
  label="Upload profile picture"
  getValueFromEvent={({file}) => file.originFileObj}
>
  <Upload
    accept="image/png, image/jpeg"
    maxCount={1}
    listType="picture-card"
    showUploadList={false}
    customRequest={dummyRequest} // to override the component sending request on image upload, see https://stackoverflow.com/a/51519603/4858751
    beforeUpload={beforeUpload} // see https://ant.design/components/upload/#components-upload-demo-avatar
    onChange={handleChange} // see https://ant.design/components/upload/#components-upload-demo-avatar
  >
    {imageUrl ? <img src={imageUrl} alt="avatar" style={{ width: '100%' }} /> : uploadButton}
  </Upload>
</Form.Item>

and the <Form>'s onFinish has to send as multipart/form-data like so:

const onFinish = async values => {
  const formData = new FormData();
  for (const name in values) {
    formData.append(name, values[name]); // there should be values.avatar which is a File object
  }
  const res = await fetch('/blabla', {
    method: 'POST',
    body: formData // automagically sets Content-Type: multipart/form-data header
  });
  // handle res however you want
}

kindly show me your handleChange();

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

10 participants