admin管理员组

文章数量:1405542

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?

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?

Share Improve this question edited Apr 24, 2020 at 21:27 jmargolisvt 6,0985 gold badges31 silver badges49 bronze badges asked Apr 24, 2020 at 21:25 freewebwithmefreewebwithme 5792 gold badges13 silver badges23 bronze badges 2
  • Are you expecting a JSON response from the server? – Terry Commented Apr 24, 2020 at 21:28
  • When you use "mode": "no-cors", not all headers you specify are allowed. Check developer.mozilla/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). – André Santos Commented Apr 24, 2020 at 21:36
Add a ment  | 

4 Answers 4

Reset to default 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 pletion 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.

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

 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.

The accepted answer solved my pinpoint.

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

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

本文标签: javascriptfetch api return wrong response objectStack Overflow