You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React自定义Hook useFetch报错:JSON解析异常求助

useFetch Hook 出现 SyntaxError: Unexpected token '<' 的原因与解决方法

错误含义

这个错误直白点说:你的Fetch请求没拿到预期的JSON数据,反而收到了HTML页面(比如开头是<doctype html>的网页)。通常是请求过程中出了问题,导致服务器返回错误页面而非API的JSON响应。

常见原因及排查修复步骤

1. 跨域请求被拦截(CORS问题)

浏览器直接访问API时可能因为API本身支持跨域,但React本地开发环境(比如localhost:3000)不在API的允许列表里,浏览器会拦截响应,此时服务器可能返回错误页面替代正常JSON。

  • 排查:打开浏览器控制台的「Network」面板,看请求的状态码和响应内容。如果是403/500状态,或者响应预览是HTML,基本就是跨域的锅。
  • 解决:
    • 开发环境下,在React项目的package.json里加一行"proxy": "你的API域名"(比如"proxy": "https://api.example.com"),让请求通过开发服务器转发。
    • 或者让API服务器配置CORS,允许你的前端域名访问。

2. 请求URL写错了

比如你用了相对路径/api/data但没配置代理,请求会打到React开发服务器(localhost:3000/api/data),而不是目标API,服务器返回的是React的首页index.html,自然会触发这个错误。

  • 排查:看Network面板里的请求地址,确认是不是目标API的正确地址。
  • 解决:要么用完整的API地址,要么配置代理后再用相对路径。

3. Fetch请求配置有遗漏

  • 没设置Accept: application/json请求头,服务器可能默认返回HTML而非JSON。
  • 直接调用response.json()但响应不是JSON,就会抛出错误。应该先检查响应状态是否正常,再解析。

修正后的useFetch Hook示例

import { useState, useEffect } from 'react';

const useFetch = (url, options = {}) => {
  const [data, setData] = useState(null);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState(null);

  useEffect(() => {
    const fetchData = async () => {
      setLoading(true);
      try {
        // 合并默认请求头,强制要求返回JSON
        const fetchOptions = {
          headers: {
            'Accept': 'application/json',
            ...options.headers,
          },
          ...options,
        };
        const response = await fetch(url, fetchOptions);
        
        // 先判断响应是否正常
        if (!response.ok) {
          throw new Error(`请求失败: ${response.status} ${response.statusText}`);
        }
        
        const result = await response.json();
        setData(result);
        setError(null);
      } catch (err) {
        setError(err.message);
        // 可以打印响应内容排查是不是HTML
        if (err.response) console.error('响应内容:', await err.response.text());
      } finally {
        setLoading(false);
      }
    };

    fetchData();
  }, [url, options]);

  return { data, loading, error };
};

export default useFetch;

TestUseFetch组件注意事项

确保传入的URL是正确的,比如:

import useFetch from './useFetch';

const TestUseFetch = () => {
  const { data, loading, error } = useFetch('https://api.example.com/your-endpoint');

  if (loading) return <div>加载中...</div>;
  if (error) return <div>出错了: {error}</div>;

  return <div>{JSON.stringify(data)}</div>;
};

export default TestUseFetch;

内容的提问来源于stack exchange,提问作者ambiasm

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.25 21:32:47