我尝试使用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()
}, [])
3条答案
按热度按时间fivyi3re1#
这种类型的错误通常发生在服务器返回不是JSON的内容时。根据我的经验,99%的情况下,服务器返回的是一般性的错误消息。通常情况下,服务器会有一个通用的“catch all”错误处理程序,它会返回如下内容:
在这种情况下,如果您尝试使用
JSON.parse
(或在您的情况下使用res.json()
),您将得到您正在经历的错误。要查看此内容,请将此粘贴到您的控制台:解决方案1:通常服务器会在出现错误时设置一个正确的状态码。在解析前检查以确保响应状态为200:
解决方案2:更新服务器代码,以JSON格式返回错误消息。如果你使用node和express,它看起来像这样:
然后,你会相应地更新你的前端代码:
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
祝你有美好的一天,编码快乐
pxiryf3j3#
试试这个方法