"Error de sintaxis: token inesperado < en JSON en la posición 0"

Resuelto Cameron Sima asked hace 8 años • 40 respuestas

En un componente de la aplicación React que maneja feeds de contenido similares a Facebook, me encuentro con un error:

Feed.js:94 undefined "parsererror" "SyntaxError: token inesperado < en JSON en la posición 0

Me encontré con un error similar que resultó ser un error tipográfico en el HTML dentro de la función de renderizado, pero ese no parece ser el caso aquí.

Lo que es más confuso es que revertí el código a una versión anterior que funciona y sigo recibiendo el 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

En las herramientas para desarrolladores de Chrome, el error parece provenir de esta función:

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

con la línea console.error(this.props.url, status, err.toString()subrayada.

Como parece que el error tiene algo que ver con la extracción de datos JSON del servidor, intenté comenzar desde una base de datos en blanco, pero el error persiste. El error parece aparecer en un bucle infinito, presumiblemente porque React intenta conectarse continuamente al servidor y finalmente bloquea el navegador.

EDITAR:

Revisé la respuesta del servidor con las herramientas de desarrollo de Chrome y el cliente REST de Chrome, y los datos parecen ser JSON adecuados.

EDITAR 2:

Parece que, aunque el punto final API previsto de hecho devuelve los datos y el formato JSON correctos, React está sondeando http://localhost:3000/?_=1463499798727en lugar del esperado http://localhost:3001/api/threads.

Estoy ejecutando un servidor de recarga en caliente de paquete web en el puerto 3000 con la aplicación express ejecutándose en el puerto 3001 para devolver los datos del backend. Lo frustrante aquí es que funcionó correctamente la última vez que trabajé en ello y no puedo encontrar qué podría haber cambiado para romperlo.

Cameron Sima avatar May 17 '16 22:05 Cameron Sima
Aceptado

La redacción del mensaje de error corresponde a lo que obtienes de Google Chrome cuando ejecutas JSON.parse('<...'). Sé que dijiste que el servidor se está configurando Content-Type:application/json, pero me hacen creer que el cuerpo de la respuesta es en realidad HTML.

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

con la línea console.error(this.props.url, status, err.toString())subrayada.

En realidad, se errlanzó dentro jQueryy se le pasó como una variable err. La razón por la que esa línea está subrayada es simplemente porque es ahí donde la está registrando.

Le sugeriría que agregue a su registro. Observe las xhrpropiedades reales (XMLHttpRequest) para obtener más información sobre la respuesta. Intente agregar console.warn(xhr.responseText)y lo más probable es que vea el HTML que se recibe.

700 Software avatar May 17 '2016 15:05 700 Software

Estás recibiendo HTML (o XML) del servidor, pero le dataType: jsondice a jQuery que lo analice como JSON. Consulte la pestaña "Red" en las herramientas de desarrollo de Chrome para ver el contenido de la respuesta del servidor.

nil avatar May 17 '2016 15:05 nil

SyntaxError: token inesperado < en JSON en la posición 0


Obtendrá un archivo HTML (o XML) en lugar de json.

Los archivos HTML comienzan con <!DOCTYPE html>.

"Logré" este error al olvidar https://en mi fetchmétodo:

fetch(`/api.github.com/users/${login}`)
    .then(response => response.json())
    .then(setData);

Verifiqué mi corazonada:

Registré la respuesta como texto en lugar de JSON.

fetch(`/api.github.com/users/${login}`)
    .then(response => response.text())
    .then(text => console.log(text))
    .then(setData);

Sí, un archivo html.

Solución:

Solucioné el error agregando nuevamente el https://en mi fetchmétodo.

fetch(`https://api.github.com/users/${login}`)
    .then(response => response.json())
    .then(setData)
    .catch(error => (console.log(error)));
Super Jade avatar Sep 25 '2020 23:09 Super Jade

Esto terminó siendo un problema de permisos para mí. Estaba intentando acceder a una URL para la que no tenía autorización con CanCan, por lo que la URL se cambió a users/sign_in. La URL redirigida responde a HTML, no a json. El primer carácter de una respuesta HTML es <.

Andrew Shenstone avatar Sep 16 '2016 22:09 Andrew Shenstone