"SyntaxError: Unexpected token < in JSON at position 0"
Solution 1
The wording of the error message corresponds to what you get from Google Chrome when you run JSON.parse('<...')
. I know you said the server is setting Content-Type:application/json
, but I am led to believe the response body is actually HTML.
Feed.js:94 undefined "parsererror" "SyntaxError: Unexpected token < in JSON at position 0"
with the line
console.error(this.props.url, status, err.toString())
underlined.
The err
was actually thrown within jQuery
, and passed to you as a variable err
. The reason that line is underlined is simply because that is where you are logging it.
I would suggest that you add to your logging. Looking at the actual xhr
(XMLHttpRequest) properties to learn more about the response. Try adding console.warn(xhr.responseText)
and you will most likely see the HTML that is being received.
Solution 2
You're receiving HTML (or XML) back from the server, but the dataType: json
is telling jQuery to parse as JSON. Check the "Network" tab in Chrome dev tools to see contents of the server's response.
Solution 3
This ended up being a permissions problem for me. I was trying to access a url I didn't have authorization for with cancan, so the url was switched to users/sign_in
. the redirected url responds to html, not json. The first character in a html response is <
.
Solution 4
In my case, I was getting this running webpack, and it turned out to be some corruption somewhere in the local node_modules dir.
rm -rf node_modules
npm install
...was enough to get it working right again.
Solution 5
SyntaxError: Unexpected token < in JSON at position 0
You are getting an HTML file (or XML) instead of json.
Html files begin with <!DOCTYPE html>
.
I "achieved" this error by forgetting the https://
in my fetch
method:
fetch(`/api.github.com/users/${login}`)
.then(response => response.json())
.then(setData);
I verified my hunch:
I logged the response as text instead of JSON.
fetch(`/api.github.com/users/${login}`)
.then(response => response.text())
.then(text => console.log(text))
.then(setData);
Yep, an html file.
Solution:
I fixed the error by adding back the https://
in my fetch
method.
fetch(`https://api.github.com/users/${login}`)
.then(response => response.json())
.then(setData)
.catch(error => (console.log(error)));
Related videos on Youtube
Cameron Sima
Full stack React.js and Spring developer in the fintech industry.
Updated on July 08, 2022Comments
-
Cameron Sima almost 2 years
In a React app component which handles Facebook-like content feeds, I am running into an error:
Feed.js:94 undefined "parsererror" "SyntaxError: Unexpected token < in JSON at position 0
I ran into a similar error which turned out to be a typo in the HTML within the render function, but that doesn't seem to be the case here.
More confusingly, I rolled the code back to an earlier, known-working version and I'm still getting the error.
Feed.js:
import React from 'react'; var ThreadForm = React.createClass({ getInitialState: function () { return {author: '', text: '', included: '', victim: '' } }, handleAuthorChange: function (e) { this.setState({author: e.target.value}) }, handleTextChange: function (e) { this.setState({text: e.target.value}) }, handleIncludedChange: function (e) { this.setState({included: e.target.value}) }, handleVictimChange: function (e) { this.setState({victim: e.target.value}) }, handleSubmit: function (e) { e.preventDefault() var author = this.state.author.trim() var text = this.state.text.trim() var included = this.state.included.trim() var victim = this.state.victim.trim() if (!text || !author || !included || !victim) { return } this.props.onThreadSubmit({author: author, text: text, included: included, victim: victim }) this.setState({author: '', text: '', included: '', victim: '' }) }, render: function () { return ( <form className="threadForm" onSubmit={this.handleSubmit}> <input type="text" placeholder="Your name" value={this.state.author} onChange={this.handleAuthorChange} /> <input type="text" placeholder="Say something..." value={this.state.text} onChange={this.handleTextChange} /> <input type="text" placeholder="Name your victim" value={this.state.victim} onChange={this.handleVictimChange} /> <input type="text" placeholder="Who can see?" value={this.state.included} onChange={this.handleIncludedChange} /> <input type="submit" value="Post" /> </form> ) } }) var ThreadsBox = React.createClass({ loadThreadsFromServer: function () { $.ajax({ url: this.props.url, dataType: 'json', cache: false, success: function (data) { this.setState({data: data}) }.bind(this), error: function (xhr, status, err) { console.error(this.props.url, status, err.toString()) }.bind(this) }) }, handleThreadSubmit: function (thread) { var threads = this.state.data var newThreads = threads.concat([thread]) this.setState({data: newThreads}) $.ajax({ url: this.props.url, dataType: 'json', type: 'POST', data: thread, success: function (data) { this.setState({data: data}) }.bind(this), error: function (xhr, status, err) { this.setState({data: threads}) console.error(this.props.url, status, err.toString()) }.bind(this) }) }, getInitialState: function () { return {data: []} }, componentDidMount: function () { this.loadThreadsFromServer() setInterval(this.loadThreadsFromServer, this.props.pollInterval) }, render: function () { return ( <div className="threadsBox"> <h1>Feed</h1> <div> <ThreadForm onThreadSubmit={this.handleThreadSubmit} /> </div> </div> ) } }) module.exports = ThreadsBox
In Chrome developer tools, the error seems to be coming from this function:
loadThreadsFromServer: function loadThreadsFromServer() { $.ajax({ url: this.props.url, dataType: 'json', cache: false, success: function (data) { this.setState({ data: data }); }.bind(this), error: function (xhr, status, err) { console.error(this.props.url, status, err.toString()); }.bind(this) }); },
with the line
console.error(this.props.url, status, err.toString()
underlined.Since it looks like the error seems to have something to do with pulling JSON data from the server, I tried starting from a blank db, but the error persists. The error seems to be called in an infinite loop presumably as React continuously tries to connect to the server and eventually crashes the browser.
EDIT:
I've checked the server response with Chrome dev tools and Chrome REST client, and the data appears to be proper JSON.
EDIT 2:
It appears that though the intended API endpoint is indeed returning the correct JSON data and format, React is polling
http://localhost:3000/?_=1463499798727
instead of the expectedhttp://localhost:3001/api/threads
.I am running a webpack hot-reload server on port 3000 with the express app running on port 3001 to return the backend data. What's frustrating here is that this was working correctly the last time I worked on it and can't find what I could have possibly changed to break it.
-
Quentin almost 8 yearsThat suggests that your "JSON" is actually HTML. Look at the data you are getting back from the server.
-
apsillers almost 8 yearsThis is the error you get if you do something like
JSON.parse("<foo>")
-- a JSON string (which you expect withdataType: 'json'
) cannot begin with<
. -
maurycy almost 8 yearsAs @quantin said, it can be html, maybe error of some sort, try the same url with some rest clients
-
Cameron Sima almost 8 yearslike I mentioned, i tried it with an empty db (which returns simply []) and it still gives the same error
-
Kevin Suttle over 7 yearsYou most likely need to proxy API requests depending on your
NODE_ENV
. See this: github.com/facebookincubator/create-react-app/blob/master/… -
Shazam almost 6 years@apsillers I think this is my problem. I am storing HTML strings with markup in my JSON object for display. Do I need to escape all the HTML characters for this to work?
-
Khurshid Ansari about 4 yearsmy suggetion to use github.com/axios/axios
-
Dante almost 3 yearsI encountered this error as I used
if($_POST['key'])
instead ofif(isset($_POST['key']))
.Although this is a very silly and an amateur mistake, I hope some LIY dev like me might find this useful. -
RohitAneja over 2 yearsCheck your package-lock.json, if there are merge conflicts, it will show this error.
-
Marina Kim almost 2 yearsHi, in my case the same issue resolved when I simply changed the API uri from root "/" to something else, e.g. app.get("/data", (req, res)...) Hope it helps someone
-
-
Cameron Sima almost 8 yearsI checked, and it appears to be returning properly formatted json. Here's the response header: Access-Control-Allow-Origin:* Cache-Control:no-cache Content-Length:2487 Content-Type:application/json; charset=utf-8 Date:Tue, 17 May 2016 15:34:00 GMT ETag:W/"9b7-yi1/G0RRpr0DlOVc9u7cMw" X-Powered-By:Express
-
Cameron Sima almost 8 yearsThanks, I did this and you're right -- react is polling the wrong url and is returning the contents of index.html. I just can't find out why.
-
user2441511 over 7 yearsThanks for the additional debugging statement, although I needed to use
console.warn(jqxhr.responseText)
. That was very helpful in diagnosing my problem. -
700 Software over 7 years@Mimi314159,
console.log
,console.warn
andconsole.error
will all write to your Console. However, the Console will usually provide Logging Filter options, so be sure that those are enabled or disabled as you prefer. -
Ivan Prihhodko almost 7 yearsThis is one of the most bizarre answers I've ever seen on Stackoverflow.
-
Derek over 6 yearsIn my case, a PHP error was occuring which caused the server to return HTML rather than valid JSON.
-
Jason Marsell over 6 yearsI had the same, although in ASP.NET MVC. For other .NETters, I had forgotten to decorate my action with the [AllowAnonymous] attribute so the framework was trying to return me the unauthorized error in HTML which was crashing my AJAX call.
-
DJ2 about 6 years@AVI I believe you have to specify the MIME type in your resource class. (e.g)
@Produces(MediaType.APPLICATION_JSON)
-
Harshith Rai over 5 yearsPlease elaborate while giving answers rather than giving one liners, unless they outright solve answers. The explanation would help the answer-seekers understand the solution better.
-
Andrew Gray about 5 yearsHi there! When posting a comment, make sure it's entirely applicable to the actual question being asked. Your answer could be better if you tell us why exactly writing comments in a
styles.less
file could possibly solve what appears to be a back-end server code issue. -
Mahesh over 4 yearsalong with this, I tried removing package-lock.json. Then it worked for me.
-
sumesh over 3 yearsPlease use the answer option if you are sure about the solution, else you can choose to write it as a comment to the question.
-
Vortex over 3 yearsIn my case this works therefore writing it as answer.
-
Shivam Jha over 3 yearsYou can also got to Developer Settings -> Network Tab to see the response which you are actually getting. This happens when you are running backend and frontend on the same sever (e.g., localhost). To fix that, in the
package.json
inside yourReact
root project folder, add this line:"proxy": "http://localhost:5000"
, (or your port instead of5000
you want your request back). -
Eliezer Berlin over 3 yearsThe reason it's happening is because you're getting an HTML response instead of a JSON response. Your response probably begins with
<head>
or<body>
, with the first letter being "<". -
Tim Erickson about 2 yearsThink carefully about that logic. Parsing
undefined
is only ONE way to get that error. Trying (for example)JSON.parse('<')
is another. -
marc-stupid about 2 yearsso what is the answer in that case
-
crwils about 2 yearsRemoving node modules and a fresh npm install worked for me.
-
Bruno71 about 2 yearsI had a similar issue with my Vue site. Locally it worked fine, but once published, I would get 404 errors when refreshing URLs. It had to do with rewriting the path for the API. I followed the Vue Router instructions here ...but it still wasn't working. I had to exclude the js/css/img directories from the redirect also.