最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - fetch api return wrong response object - Stack Overflow

programmeradmin4浏览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?

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())
发布评论

评论列表(0)

  1. 暂无评论