I know there are a few question about this topic. I applied at them but I still get this error
Uncaught (in promise) SyntaxError: Unexpected token < in JSON at position 0
this code works other APIs
getData() {
fetch('http://localhost:50/data', {
headers : {
'Content-Type': 'application/json',
'Accept': 'application/json'
}
})
.then((response) => { return response.json(); })
.then((result) => {
console.log(result);
});
}
php code
header('Access-Control-Allow-Origin: *');
header('Content-type:application/json;charset=utf-8');
echo json_encode(['data' => 'test']);
That unexpected < probably means you got back HTML instead of JSON. Log the response and read it, it may be an error message from your server.
Developer Mozilla has a good guide for using fetch, especially for beginners.
I actually just faced with the same problem earlier and after searching for a few hours with no luck, so I experimented on it and finally got it working.
I copy pasted the sample codes on Developer Mozilla with the complete initialized values for the object after the url
fetch(url, {
body: JSON.stringify(data), // must match 'Content-Type' header
cache: 'no-cache', // *default, no-cache, reload, force-cache, only-if-cached
credentials: 'same-origin', // include, same-origin, *omit
headers: {
'user-agent': 'Mozilla/4.0 MDN Example',
'content-type': 'application/json'
},
method: 'POST', // *GET, POST, PUT, DELETE, etc.
mode: 'cors', // no-cors, cors, *same-origin
redirect: 'follow', // manual, *follow, error
referrer: 'no-referrer', // *client, no-referrer
})
.then(response => response.json())
and it worked, so I tried removing each property to see if removing it will cause the error again and I found out that removing the credentials: 'same-origin will cause the error I experienced earlier.
You forgot to put a method: 'GET' on your code. Your final code should look like this. Hope it helps.
fetch('http://localhost:50/data', {
method: 'GET',
credentials: 'same-origin',
headers : {
'Content-Type': 'application/json',
'Accept': 'application/json'
}
})
.then((response) => { return response.json(); })
.then((result) => {
console.log(result);
});
Related
I am trying to build a frontend interface to communicate with an API service, I am using HTML,CSS & JavaScript. I am using async function / await fetch to call the API and response.jsom to retrieve the Json data from the response, now I have to add X-Authorization:Bearer Token '.....' to the header, how can I do that with JavaScript?
thanx for help
Add your token inside the header, here is an example, call this postData function anywhere from your application, you can add it in a common place
Also check
https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch
this for the detailed explanation
// Example POST method implementation:
async function postData(url = '', data = {}) {
// Default options are marked with *
let token = "Get your token here, Store it in local storage and read it from local storage is a better method"
const response = await fetch(url, {
method: 'POST', // *GET, POST, PUT, DELETE, etc.
mode: 'cors', // no-cors, *cors, same-origin
cache: 'no-cache', // *default, no-cache, reload, force-cache, only-if-cached
credentials: 'same-origin', // include, *same-origin, omit
headers: {
'Content-Type': 'application/json',
"X-Authorization":Bearer Token '.....' // Here you can add your token
},
redirect: 'follow', // manual, *follow, error
referrerPolicy: 'no-referrer', // no-referrer, *no-referrer-when-downgrade, origin, origin-when-cross-origin, same-origin, strict-origin, strict-origin-when-cross-origin, unsafe-url
body: JSON.stringify(data) // body data type must match "Content-Type" header
});
return response.json(); // parses JSON response into native JavaScript objects
}
postData('https://example.com/answer', { answer: 42 })
.then(data => {
console.log(data); // JSON data parsed by `data.json()` call
});
How to set header and parameter for route.get in node js?
I want to set header value and parameter to API data call URL.
router.get("/getdata", async (req, res) => {
res.header({
'key': '123456'
});
await fetch(`https://example.com/api?param=${data}`)
.then((data) => data.json())
.then((data) => res.json({ msg: data }))
.catch((err) => console.log(err));
});
my question is how to set header and parameter data in router.get in node js ?
The question is not clear and you should add more details to it and ask the specific things which might be causing an issue.
Headers are set on the response which can be done directly on res object like this:
res.set({
'Content-Type': 'text/plain',
'Content-Length': '123',
'ETag': '12345'
})
Check this for more details.
If you need to set headers on fetch API call, You can do that directly on fetch as below:
async function postData(url = '', data = {}) {
// Default options are marked with *
const response = await fetch(url, {
method: 'POST', // *GET, POST, PUT, DELETE, etc.
mode: 'cors', // no-cors, *cors, same-origin
cache: 'no-cache', // *default, no-cache, reload, force-cache, only-if-cached
credentials: 'same-origin', // include, *same-origin, omit
headers: {
'Content-Type': 'application/json'
// 'Content-Type': 'application/x-www-form-urlencoded',
},
redirect: 'follow', // manual, *follow, error
referrerPolicy: 'no-referrer', // no-referrer, *no-referrer-when-downgrade, origin, origin-when-cross-origin, same-origin, strict-origin, strict-origin-when-cross-origin, unsafe-url
body: JSON.stringify(data) // body data type must match "Content-Type" header
});
return response.json(); // parses JSON response into native JavaScript objects
}
If you want to read params in the req object:
router.get("/getdata", async (req, res) => {
const query = req.query // its an object containing all the params
await fetch(`https://example.com/api?param=${data}`)
.then((data) => data.json())
.then((data) => res.json({ msg: data }))
.catch((err) => console.log(err));
});
Read the documentation for Express around routing. It explains on how to e.g. use req.query to access the param in that fetch URL.
All my GET requests are going through but POST ones fail. This happens when I update fetch-mock from 7.3.0 to 7.3.1 or later.
console.warn Unmatched POST to url
Error fetch-mock: No fallback response defined for POST to url
http.js
export const get = (url) => {
const options = {
method: 'GET',
credentials: 'same-origin'
};
return fetch(url, options).then(handleJsonResponse);
};
export const post = (url, body) => {
const headers = {
'content-type': 'application/json',
'pragma': 'no-cache',
'cache-control': 'no-cache'
};
return fetch(url, {
credentials: 'same-origin',
method: 'POST',
cache: 'no-cache',
body: JSON.stringify(body),
headers
}).then(handleJsonResponse);
};
http.spec.js
const url = '/path/to/url'
describe('get', () => {
it('makes a GET request', async () => {
fetchMock.mock({
name: 'route',
matcher: url,
method: 'GET',
credentials: 'same-origin',
response: {
status: 200,
body: []
}
});
const response = await get(url);
expect(fetchMock.called()).toEqual(true);
expect(fetchMock.calls().length).toEqual(1);
expect(fetchMock.calls('route').length).toEqual(1);
expect(response).toEqual([]);
});
});
describe('post', () => {
const requestBody = {request: 'request'};
it('makes a POST request', async () => {
fetchMock.mock({
name: 'route',
matcher: url,
method: 'POST',
credentials: 'same-origin',
cache: 'no-cache',
body: JSON.stringify(requestBody),
headers: {
'content-type': 'application/json',
'pragma': 'no-cache',
'cache-control': 'no-cache'
},
response: {
status: 200,
body: []
}
});
const response = await post(url, requestBody);
expect(fetchMock.called()).toEqual(true);
expect(fetchMock.calls().length).toEqual(1);
expect(fetchMock.calls('route').length).toEqual(1);
expect(fetchMock.lastOptions().headers).toEqual({
'content-type': 'application/json',
'pragma': 'no-cache',
'cache-control': 'no-cache'
});
expect(response).toEqual([]);
});
});
Any thoughts on what's causing this? Is there a way to get more meaningful logs to help with debugging this?
I would rather not go the alternative path of trying nock or jest-fetch-mock.
Alright, after hours of digging into the library itself I have found out where the issue was.
In my code (and the snippet above) I am stringifying the body JSON.stringify(body). The library's generate-matcher.js is parsing it JSON.parse(body) and then compares the two - the point which was causing the failure. I am now just sending it as the raw object.
In case anyone else ends up here in the future, I had the same error accompanied with fetch-mock unmatched get.
I saw the response to this issue filed to fetch-mock which prompted me to double check my expected values and mocked values.
It turns out my problem was exactly as the error described, where the mock route I was expecting and the actual route that was being called were mismatched because of a typo.
I want to use the new Fetch in javascript to do an ajax request. This is the code I've written for that
// Example POST method implementation:
var initial_data = {
'id': 1,
'model-name': 'Joke'
};
postData('/start-jokes', initial_data)
.then(data => console.log(data)) // JSON from `response.json()` call
.catch(error => console.error(error))
function postData(url, data) {
// Default options are marked with *
return fetch(url, {
body: JSON.stringify(data), // must match 'Content-Type' header
cache: 'no-cache', // *default, no-cache, reload, force-cache, only-if-cached
credentials: 'same-origin', // include, same-origin, *omit
headers: {
'user-agent': 'Mozilla/4.0 MDN Example',
'content-type': 'application/json'
},
method: 'POST', // *GET, POST, PUT, DELETE, etc.
mode: 'cors', // no-cors, cors, *same-origin
redirect: 'follow', // manual, *follow, error
referrer: 'no-referrer', // *client, no-referrer
})
.then(response => response.json()) // parses response to JSON
}
but it throws an error on load like so
SyntaxError: JSON.parse: unexpected character at line 1 column 1 of the JSON data
Trying it out on the console this is the response also of calling postData
Promise { <state>: "pending" }
SyntaxError: JSON.parse: unexpected character at line 1 column 1 of the JSON data
Don't use then(response => response.json() in fetchData like this. If there is an error when you call API, you can't catch that.
// Example POST method implementation:
var initial_data = {
'id': 1,
'model-name': 'Joke'
};
postData('/start-jokes', initial_data)
.then(response => response.json()) // parses response to JSON
.then(data => console.log(data)) // JSON from `response.json()` call
.catch(error => console.error(error))
function postData(url, data) {
// Default options are marked with *
return fetch(url, {
body: JSON.stringify(data), // must match 'Content-Type' header
cache: 'no-cache', // *default, no-cache, reload, force-cache, only-if-cached
credentials: 'same-origin', // include, same-origin, *omit
headers: {
'user-agent': 'Mozilla/4.0 MDN Example',
'content-type': 'application/json'
},
method: 'POST', // *GET, POST, PUT, DELETE, etc.
mode: 'cors', // no-cors, cors, *same-origin
redirect: 'follow', // manual, *follow, error
referrer: 'no-referrer', // *client, no-referrer
})
}
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.