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
4 Answers
Reset to default 4If 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())