React Native fetch返回SyntaxError:JSON中位置0处的意外标记T

cgh8pdjw  于 2023-10-23  发布在  React
关注(0)|答案(3)|浏览(119)

我尝试使用JavaScript的fetch方法,但是,它似乎不能异步工作。
下面是我的代码:

fetch(`${global.URL}${url}`, requestConfig)
  .then(res => res.json())
  .then(res => {
    console.log('response', res);
    return res;
  })
  .catch(error => {
    console.log('error: ', error)
  })

我得到以下错误70%的时间,然后其他30%,收到一个有效的响应,当我保存文件,它重新呈现,它有时工作。

error:  SyntaxError: Unexpected token T in JSON at position 0
    at parse (<anonymous>)
    at tryCallOne (core.js:37)
    at core.js:123
    at JSTimers.js:277
    at _callTimer (JSTimers.js:135)
    at _callImmediatesPass (JSTimers.js:183)
    at Object.callImmediates (JSTimers.js:446)
    at MessageQueue.__callImmediates (MessageQueue.js:396)
    at MessageQueue.js:144
    at MessageQueue.__guard (MessageQueue.js:373)

我试过在内部调用它和blog/await函数,但它没有帮助。
编辑1:
这就是我提出要求的方式

const authenticityToken = global.TOKEN

const query = (url, config) => {
  const requestConfig = {
    credentials: 'same-origin',
    ...config,
    headers: {
      'X-Requested-With': 'XMLHttpRequest',
      'Content-Type': 'application/json',
      Accept: 'application/json',
      Authorization: authenticityToken,
    },
  }

  return fetch(`${global.URL}${url}`, requestConfig)
  .then(res => res.json())
  .then(res => {
    console.log('response', res);
    return res;
  })
  .catch(error => {
    console.log('error: ', error)
  })
  // .then(handleResponseError)
}

export const get = (url, data) =>
  query(data ? `${url}?${stringify(data)}` : url)

export function fetchUser() {
  return (
    get('/api/v3/me/')
  )
}

然后我在我的组件中调用函数,如下所示:

const fetchUserAction = () => {
    fetchUser()
    .then((response) => {
      if(response) setUser(response.data)
    })
  }

  useEffect(() => {
    fetchUserAction()
  }, [])
fivyi3re

fivyi3re1#

这种类型的错误通常发生在服务器返回不是JSON的内容时。根据我的经验,99%的情况下,服务器返回的是一般性的错误消息。通常情况下,服务器会有一个通用的“catch all”错误处理程序,它会返回如下内容:

There was an error processing your request.

在这种情况下,如果您尝试使用JSON.parse(或在您的情况下使用res.json()),您将得到您正在经历的错误。要查看此内容,请将此粘贴到您的控制台:

JSON.parse("There was an error processing your request.")
//-> Uncaught SyntaxError: Unexpected token T in JSON at position 0

解决方案1:通常服务器会在出现错误时设置一个正确的状态码。在解析前检查以确保响应状态为200:

fetch('...').then(res => {
  if (res.status !== 200) {
    throw new Error(`There was an error with status code ${res.status}`)
  }
  return res.json()
)

解决方案2:更新服务器代码,以JSON格式返回错误消息。如果你使用node和express,它看起来像这样:

function errorHandler (err, req, res, next) {
  if (res.headersSent) return next(err)

  const message = 'There was an error processing your request.'
  res.status(500)
  if (req.accepts('json')) {
    // The request contains the "Accept" header with the value "application/json"
    res.send({ error: message });
    return;
  }
  res.send(message);
}

然后,你会相应地更新你的前端代码:

fetch('...')
.then(res => res.json())
.then(res => {
  if (res.error) {
    throw new Error(res.error)
  }
  return res
)
e5njpo68

e5njpo682#

当您试图解析的字符串无法解析为JSON时,通常会发生这种错误Unexpected token T in JSON at position 0。此特定错误意味着字符串以字符'T'开头,而不是以'{'开头,因为可以解析为JSON的字符串应该以'{'开头。有一个非常严格的格式允许你的字符串成为一个对象。如果你在后端确保你的代码接受一个对象,对它进行字符串化,并发送文本,这可能不是问题。如果你知道在后端,唯一可以发送的是一个字符串化的对象,那么这里可能没有什么问题。
第二个更合理的答案是你的请求失败了,我看到你准备了一个catch块,以防请求返回一个错误,但这里有一个问题。请求失败可能有几个原因,如果你说它只发生在某些时候,它可能是CORS问题或后端的逻辑错误。在这种情况下,您希望看到响应本身,而不是已经解析的响应。实际上,当你的请求成功时,主体被成功解析为一个对象,一切正常,但是当请求失败时,响应将是一个以T开头的异常,例如,当你试图解析它时,TimeoutException失败了,因为它以T开头,而不是JSON。您需要看到的是在解析为JSON之前的响应,只有当它不是错误时,您才应该尝试解析它。
代码中的问题是,您要做的第一件事是尝试将其解析为JSON。我建议您注解掉这一行,并简单地将成功的请求或失败的请求打印为字符串。我敢肯定你会发现,在70%的时间里,你会看到你所期望的JSON字符串,在剩下的30个时间里,你会得到一个异常字符串(甚至可能是由你的后端托管服务自动抛出的,比如异常,它们可能不会被视为错误,而是被视为字符串。不幸的是,这在Firebase函数的免费计划中经常发生,其中函数运行的时间被限制在一定的秒数内,您应该在其网站上的计划描述中检查它)以T开头。这肯定会帮助你找到问题所在,给你更多的信息。
另一方面,我强烈建议您停止使用then and catch,而是开始使用更高级的上级bloc/await语法,它可以帮助您保持代码的简单性和组织性。如果它与您的目标引擎兼容,请阅读Mozilla文档,它非常简单:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function
祝你有美好的一天,编码快乐

pxiryf3j

pxiryf3j3#

试试这个方法

const response = await fetch('https://apitest.authorize.net/xml/v1/request.api', {
    method: 'post',
    body: JSON.stringify(jsonBody),
    headers: new Headers({'content-type': 'application/json',Accept: 'application/json',}),
    
});

const text = await response.text();
console.log(text);
   

return new Response(text, { status: 200, statusText: 'OK', headers: { 'Content-Type': 'application/json' } });

相关问题