Im trying to make a request from my React App to my backend server, the frontend do a OPTIONS request and that is OK, the problem is that my then on the fetch console logs the OPTIONS response, and not the real response that is made efter the OPTIONS request.
fetch('http://localhost:8080/api/kp/ticket', {
headers: {
"token": sessionStorage.getItem('token')
},
mode: 'cors',
method: 'GET'
}).then(data => console.log(data));
try this
fetch('http://localhost:8080/api/kp/ticket', {
headers: {
"token": sessionStorage.getItem('token')
},
mode: 'cors',
method: 'GET'
}).then(data => (data.json())
.then(res => console.log(res));
Check in "Other" tab in chrome devtools. Not in XHR
Related
I am trying to send a GET request and receive a response on my client side (react).
On my express server:
app.get('/', function (req, res) {
res.send('Hey, I came from the express server');
})
When I use postman to sent the request I receive a good answer:
So I don't think the problem is with the server.
A problem:
When I try to send the request using react like this:
const getData = () => {
fetch("http://localhost:8081", {
method: "GET",
mode: 'no-cors'
}).then(response => console.log(response));
}
For some reason the response status is 0 and not 200 (I am receiving status code of 200 when checking this request with postman and also on the chrome network tab).
In addition, if I try to print response.body it will be null.
The response:
body: (...)
bodyUsed: false
headers: Headers {}
ok: false
redirected: false
status: 0
statusText: ""
type: "opaque"
url: ""
[[Prototype]]: Response
What am I doing wrong here?
You can add a proxy property to your package.json:
"proxy": "http://localhost:8081",
And then just use / as your fetch endpoint.
fetch('/'...
You need to transfer your response to an text or json like:
const getData = () => {
fetch("http://localhost:8081", {
method: "GET",
mode: 'no-cors'
}).then(response => response.json()).then(data => console.log(data))
}
Besides .json() there are even more methods. Its everything written down in the docs. You just need to google it:
https://developer.mozilla.org/en-US/docs/Web/API/Response#methods
I have a function which uses Axios to send a POST request which goes through successfully and I get the right response. Now I want to try using fetch to do the exact same POST request. Unfortunately, the fetch request returns a 415 Unsupported Media Type response error and I have no idea why.
Currently:
onBeforeUnload = () => {
try {
const defaultPresence = {
presence: 'AVAILABLE',
message: '',
};
const url = getServerURL() + urls.PRESENCE;
axios.post(
url,
defaultPresence,
{
headers: {
Authorization: `Bearer ${getAccessToken()}`,
},
},
);
} catch (error) {
console.log(error);
}
}
The fetch code I've used to replace the Axios POST request.
fetch(url, {
method: 'POST',
headers: {
Authorization: `Bearer ${getAccessToken()}`,
},
body: defaultPresence,
});
fetch does not recognise plain objects as the body.
If you want to send JSON then you need to encode the data and set the content-type header yourself.
fetch(url, {
method: 'POST',
headers: {
Authorization: `Bearer ${getAccessToken()}`,
"Content-Type": "application/json",
},
body: JSON.stringify(defaultPresence),
});
I am using the fetch api to get an access token returned from the github api.
When I check the network tab I see that the token is returned but I am unable to access it in my fetch request.
My code looks like this:
fetch(`https://github.com/login/oauth/access_token?client_id=***&client_secret=***&code=${code}&redirect_uri=http://localhost:3000/&state=react`, {
method: 'POST',
mode: 'no-cors',
headers: new Headers({
'Content-Type': 'application/json'
})
}).then(function(res) {
console.log(res); // I have already tried return res.json() here
})
The console displays the following error if I return res.json():
index.js:30 Uncaught (in promise) SyntaxError: Unexpected end of input
The GitHub docs states the response takes the following format:
By default, the response takes the following form:
access_token=e72e16c7e42f292c6912e7710c838347ae178b4a&token_type=bearer
I guess it isn't returning valid json but just a string so I am not sure how to access this response.
The response looks like this:
However, when I try and log out the response I get SyntaxError: Unexpected end of input
If you are using mode: 'no-cors, browser will restrict to access body. Browser has security for cross domain. If you want to access body you have to call without mode: 'no-cors property.
https://developer.mozilla.org/en-US/docs/Web/API/Request/mode
This will work
fetch(`https://jsonplaceholder.typicode.com/posts/1`, {
method: 'GET',
headers: new Headers({
'Content-Type': 'application/json'
})
})
.then(res => res.json())
.then(function(res) {
console.log(res);
})
This will not work
fetch(`https://jsonplaceholder.typicode.com/posts/1`, {
method: 'GET',
mode: 'no-cors',
headers: new Headers({
'Content-Type': 'application/json'
})
})
.then(res => res.json())
.then(function(res) {
console.log(res);
})
I think you're almost there. You've mentioned this link to the docs. If you read further, you can see that to get response in JSON, you need to include a header named Accept with the value of application/json.
fetch(` ... `, {
method: 'POST',
mode: 'no-cors',
headers: new Headers({
'Content-Type': 'application/json',
'Accept': 'application/json'
})
}).then(function(res) {
...
})
This way, you can apply .json() on res.
I have a fetch request within the componentDidMount() method of a React component:
const request = new Request(url, {
mode: 'no-cors',
method: 'get',
headers: {
Accept: 'application/json'
}
});
fetch(request)
.then(function(response) {
console.log('Response: ', response);
return response.text();
})
.then(function(data) {
// _this.setState({ data: data });
console.log('Success: ', data);
console.log('Request succeeded with JSON response', data);
}).catch(function(error) {
console.log('Request failed', error);
});
When the Component loads, I can see the Request being made in the Console and the proper data being returned; however, my Response object is always empty:
Response { type: "opaque", url: "", redirected: false, status: 0, ok: false, statusText: "", headers: Headers, bodyUsed: false }
response.text() returns null, and I'm really uncertain what is going on. I've used the same method before and not had this problem, so I'm uncertain if it's different because of the third-party data source or what.
Any ideas?
I suggest you to follow the comments below the question:
sideshowbarker says
If the reason you’re using mode: 'no-cors' is because the server doesn’t send the Access-Control-Allow-Origin response header in its responses, then mode: 'no-cors' is not the way to fix that. The only way to fix it properly is to either configure the server to send Access-Control-Allow-Origin response header or else change your frontend JavaScript code to make you request through a proxy instead. follow this link...
My RESTful service allows batching requests.
I'm trying to combine requests into one batch with help of Fetch API:
let req1 = {
url: "/cups/count",
options: {
method: 'GET',
headers: {
'Content-Type': 'application/http'
}
}
},
req2 = {
url: "/spoons/count",
options: {
method: 'GET',
headers: {
'Content-Type': 'application/http'
}
}
},
authToken = "Bearer my_token123",
batchUrl = "http://something.com/batch",
options = {
method: 'POST',
headers: {
'Authorization': authToken,
'Content-Type': 'multipart/mixed'
},
body: {req1, req2}
};
return fetch(batchUrl, options)
.then(response => response.json())
.then(items => dispatch(batchSuccess(items)))
.catch((err) => {
console.log(err)
});
However it returns an error - bad request. I suppose I may combine HTTP requests in wrong way.
Is there simpler way of doing this?
Where in Network Chrome Dev Tools can I see nested HTTP requests?
Your code does not work because it does not follow multipart/mixed request format:
In Content-Type header, there is no boundary information.
The child requests are not divided by boundary, instead they will be sent as plain text of req1 & req2 object.
In order to send valid multipart/mixed request, there is a node.js module batchelor. According to the introduction page, its usage is pretty simple.
If you want to send multipart/mixed request from browser, you can use build tool (gulp, webpack etc.) to compile batchelor into something like "batchelor-compiled.js" and import it in HTML.
For developer tool, I didn't find anything in Chrome, but the child requests are visible in Firefox debug window's "Params" tab.
Here is an example of a batch request using the Fetch API with the Gmail Batch REST API.
This will get the content of several messages at once.
const response = await fetch("https://www.googleapis.com/batch/gmail/v1", {
headers: {
"Content-Type": "multipart/mixed; boundary=batch_boundary",
Authorization: "Bearer <access_token>",
},
method: "POST",
body: `--batch_boundary
Content-Type: application/http
Content-ID: 1
GET /gmail/v1/users/me/messages/{message-id-1}
--batch_boundary
Content-Type: application/http
Content-ID: 2
GET /gmail/v1/users/me/messages/{message-id-2}
--batch_boundary--`,
});
console.log(await response.text());