0

I am posting request to my backend server using fetch api in React js

const formData = new FormData();
    formData.append("image", file);
    formData.append("userId", currentUser.id);
    formData.append("sliderNumber", sliderNumber);

    const myHeaders = new Headers();
    myHeaders.append("Content-Type", file.type);
    myHeaders.append("Aceess-Control-Allow-Origin", "*");

    fetch("http://localhost:4000/upload/slide-image", {
      method: "POST",
      headers: myHeaders,
      mode: "no-cors",
      body: formData
    })
      .then(response => response)
      .then(data => console.log("Printing data: ", data));
  };

In elixir backend

def upload(conn, params) do
  # uploading code 

  #send response to the client with amazon s3 image url
  send_resp(conn, 200, image_url)
end

but Response object from fetch api is empty

Response {
  body: null
  bodyUsed: false
  headers: Headers {}
  ok: false
  redirected: false
  status: 0
  statusText: ""
  type: "opaque"
  url: ""
}

And it doesn't change when I respond with status code 400.

It seems like fetch api is not building Reponse object correctly in some point. Because I can find correct status code and response body in browser network tab. But Response object doesn't hold response from backend server.

Any idea?

2
  • Are you expecting a JSON response from the server? Commented Apr 24, 2020 at 21:28
  • When you use "mode": "no-cors", not all headers you specify are allowed. Check developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch for more info. Since in headers you are allowing cors, i think you probably mean to remove the "mode": "no-cors" bit. Also, you probably mean something else with .then(response => response). Commented Apr 24, 2020 at 21:36

4 Answers 4

4

If you are expecting a text response from your server, then on your first .then(.. you should do like:

fetch("http://localhost:4000/upload/slide-image", {
      method: "POST",
      headers: myHeaders,
      mode: "no-cors",
      body: formData
    })
      .then(response => response.text()) // <--- 
      .then(data => console.log("Printing data: ", data));

fetch returns a Promise that resolves to a Response. When you use .text() at this stage, what you actually do is to take the Response stream, read it to completion and return a promise that will resolve with a text.

Aside from that, you also use mode: "no-cors" (as other users mentioned on their answers) that limits you in many ways. For example, even if you follow my instructions above, you will get an empty string, even if you are trying to return something from your server. And that will be because of this mode.

You can find more details about it here, under bullet no-cors.

Sign up to request clarification or add additional context in comments.

Comments

3

Your Content-Type is wrong. When sending files along with other data, the Content-Type should still be multipart/form-data.

Comments

1
 mode: "no-cors",

You set the mode to no-cors, so the response is Opaque, which means you can't see inside it.

Don't do that if you need to read the response.


Asides:

myHeaders.append("Content-Type", file.type);

That's the wrong content-type for a form data object. Don't set the content-type. The fetch API will set the correct one automatically.

   myHeaders.append("Aceess-Control-Allow-Origin", "*");

Access-Control-Allow-Origin, which you misspelt, is a response header, not a request header.

.then(response => response)

Returning the response unchanged is rather pointless. You probably want response.text() if you are getting a plain URL back.

Comments

0

The accepted answer solved my pinpoint.

if you are expecting a JSON object from the backend, use

.then((response) => response.json())

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.