developit/unfetch

Bad post request (status 400) creates CORS error

Moshyfawn opened this issue · 4 comments

When I'm trying to upload an image object using FormData() via input type="file", server responds with status 400 (Bad request)

Sending data without JSON.stringify() throws a CORS error in a console Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at http://backend/api/v1/images. (Reason: CORS header ‘Access-Control-Allow-Origin’ missing). If I change my headers to "Content-Type": "multipart/form-data" the error goes away but server still responds with error status 400. Enabling CORS addon does the same: no console error but Bad request
I also allow cross-origin access via Access-Control-Allow-Origin: * on server

Here's my function that handles POSTing an image to server and getting its id back:

<input type='file' name='product_image' label='Product image' onChange={this.handleUpload} />

handleUpload () => {
 let file = e.target.files[0]
 let data = new FormData()
 data.append('image[file]', file),
 data.append('image[type]', 'product')
 const image = await fetch('https://backend/api/v1/images', {
  method: 'POST',
  headers: {
   'Content-Type': 'application/json',
  },
  body: JSON.stringify(data)
 })
 if (image) {
  this.setState({ imgId: image.id })
 }
}

My dev. env.:
Server: Ubuntu server 18.04 machine
Backend: Fenix 1.3
Web app: Next.js 8.0.3
No proxy used

I resolved my problem with switching to axios library after trying to solve it on stack overflow

I expect to upload an image object to get its server url to use onSubmit() to change an existing one.

Correct me if i am wrong but is this not a specification of CORS, that there are no errors available in JS code?

CORS failures result in errors, but for security reasons, specifics about what went wrong are not available to JavaScript code. All the code knows is that an error occurred. The only way to determine what specifically went wrong is to look at the browser's console for details.

https://developer.mozilla.org/de/docs/Web/HTTP/CORS#Functional_overview

@FleMo93, It is indeed a CORS feature to secure error information. I don't have any problems in this regard. I'm trying to figure out the way of sending my POST request with this unfetch library. The only solution I found is to just switch to axios. So, I figured I'd ask here if it is a library issue

@Moshyfawn When i tested this library i had problems with CORS in my project. But i read deeper into the CORS policy and find out it had to do with simple requests and requests who need a preflight. The errors where on the server. I first started with "whatwg-fetch" and i gone back to it.
I tested unfetch now and it seems like everything is working fine. Except some error handling. My project is using simple requests and also requests using a preflight.

Apologies for not responding sooner - this is actually just the way CORS works. When switching to Axios, you likely also stopped calling JSON.stringify() on your FormData object, which is what fixed the bug. You can't JSON.stringify formData, it must be passed as the body of the request directly:

 let file = e.target.files[0]
 let data = new FormData()
 data.append('image[file]', file),
 data.append('image[type]', 'product')
 const image = await fetch('https://backend/api/v1/images', {
  method: 'POST',
  headers: {
   'Content-Type': 'multipart/form-data',
  },
  body: data
 })
 if (image) {
  this.setState({ imgId: image.id })
 }

This isn't a bug in Unfetch, but perhaps is a bit of a DX issue with the Fetch API and FormData.