327 votes

"Erreur de syntaxe : Unexpected token < in JSON at position 0" (Unxpected token < dans JSON à la position 0)

Dans un composant d'application React qui gère des flux de contenu de type Facebook, je rencontre une erreur :

Feed.js:94 undefined "parsererror" "SyntaxError : Unxpected token < in JSON at position 0".

J'ai rencontré une erreur similaire qui s'est avérée être une faute de frappe dans le HTML de la fonction de rendu, mais cela ne semble pas être le cas ici.

Plus déroutant encore, j'ai ramené le code à une version antérieure, connue pour fonctionner, et j'obtiens toujours l'erreur.

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

Dans les outils de développement de Chrome, l'erreur semble provenir de cette fonction :

 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)
    });
  },

avec la ligne console.error(this.props.url, status, err.toString() soulignés.

Puisque l'erreur semble avoir un rapport avec l'extraction de données JSON du serveur, j'ai essayé de démarrer à partir d'une base de données vierge, mais l'erreur persiste. L'erreur semble être appelée dans une boucle infinie, vraisemblablement parce que React essaie continuellement de se connecter au serveur et finit par faire planter le navigateur.

EDIT :

J'ai vérifié la réponse du serveur avec Chrome dev tools et Chrome REST client, et les données semblent être du JSON correct.

EDIT 2 :

Il semble que, bien que le point de terminaison de l'API prévu renvoie effectivement les données et le format JSON corrects, React interroge les données de l'API. http://localhost:3000/?_=1463499798727 au lieu de l'attendu http://localhost:3001/api/threads .

J'exécute un serveur de recharge à chaud de webpack sur le port 3000 avec l'application express s'exécutant sur le port 3001 pour renvoyer les données du backend. Ce qui est frustrant ici, c'est que cela fonctionnait correctement la dernière fois que j'ai travaillé dessus et je n'arrive pas à trouver ce que j'aurais pu changer pour le casser.

24 votes

Cela suggère que votre "JSON" est en fait du HTML. Regardez les données que vous recevez en retour du serveur.

3 votes

C'est l'erreur que vous obtenez si vous faites quelque chose comme JSON.parse("<foo>") -- une chaîne JSON (ce que vous attendez avec dataType: 'json' ) ne peut pas commencer par < .

0 votes

Comme @quantin l'a dit, cela peut être du html, peut-être une erreur, essayez la même url avec d'autres clients.

227voto

George Bailey Points 13735

Le libellé du message d'erreur correspond à ce que vous obtenez de Google Chrome lorsque vous exécutez JSON.parse('<...') . Je sais que vous avez dit que le serveur est réglé Content-Type:application/json mais je suis amené à croire que la réponse corps est en fait du HTML.

Feed.js:94 undefined "parsererror" "SyntaxError: Unexpected token < in JSON at position 0"

avec la ligne console.error(this.props.url, status, err.toString()) soulignés.

El err a en fait été jeté dans jQuery et vous est transmis en tant que variable err . La raison pour laquelle cette ligne est soulignée est simplement que c'est là que vous l'enregistrez.

Je vous suggère d'ajouter à votre journal de bord. En regardant l'actuel xhr (XMLHttpRequest) pour en savoir plus sur la réponse. Essayez d'ajouter console.warn(xhr.responseText) et vous verrez très probablement le HTML qui est reçu.

6 votes

Merci, j'ai fait cela et vous avez raison - react interroge la mauvaise url et renvoie le contenu de index.html. Je n'arrive pas à trouver pourquoi.

11 votes

Merci pour la déclaration de débogage supplémentaire, bien que j'aie eu besoin d'utiliser console.warn(jqxhr.responseText) . Cela a été très utile pour diagnostiquer mon problème.

0 votes

@Mimi314159, console.log , console.warn y console.error écriront tous sur votre console. Cependant, la console fournit généralement des options de filtre de journalisation, alors assurez-vous que celles-ci sont activées ou désactivées selon vos préférences.

88voto

nil Points 34

Vous recevez du HTML (ou du XML) en retour du serveur, mais l'adresse IP de l'utilisateur ne correspond pas à celle du serveur. dataType: json indique à jQuery d'analyser les données en JSON. Vérifiez l'onglet "Network" dans Chrome dev tools pour voir le contenu de la réponse du serveur.

0 votes

J'ai vérifié, et il semble qu'il renvoie un json correctement formaté. Voici l'en-tête de la réponse : 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

1 votes

@AVI Je crois que vous devez spécifier le type MIME dans votre classe de ressources. (par exemple) @Produces(MediaType.APPLICATION_JSON)

17voto

Cela s'est avéré être un problème de permissions pour moi. J'essayais d'accéder à une url pour laquelle je n'avais pas d'autorisation avec cancan, donc l'url a été changée en users/sign_in . l'url redirigée répond au html, pas au json. Le premier caractère d'une réponse html est < .

0 votes

Et quand vous recevez un HTML comme réponse comment pouvez-vous rediriger vers ce html ? Merci.

1 votes

J'ai eu le même problème, mais en ASP.NET MVC. Pour les autres utilisateurs de .NET, j'avais oublié d'agrémenter mon action de l'attribut [AllowAnonymous] et le framework essayait de me renvoyer l'erreur non autorisée en HTML, ce qui faisait échouer mon appel AJAX.

12voto

Kev Points 5046

Dans mon cas, j'ai eu ce problème en exécutant webpack, et il s'est avéré être une corruption quelque part dans le répertoire local node_modules.

rm -rf node_modules
npm install

...était suffisant pour le faire fonctionner à nouveau.

1 votes

En même temps, j'ai essayé de supprimer package-lock.json. Ensuite, cela a fonctionné pour moi.

10voto

VictorL Points 141

J'ai rencontré cette erreur "SyntaxError : Unexpected token m in JSON at position", où le jeton 'm' peut être n'importe quel autre caractère.

Il s'est avéré que j'ai manqué l'un des guillemets dans l'objet JSON lorsque j'ai utilisé RESTconsole pour le test de la DB, comme {"nom : "math"}, le correct devrait être {"nom" : "math"}

Il m'a fallu beaucoup d'efforts pour comprendre cette erreur maladroite. Je crains que d'autres ne rencontrent des problèmes similaires.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X