React Query请求返回HTML而非数据,求排查解决方法
React Query请求json-server返回HTML文档问题排查
问题现象
使用自定义React Query Hook请求json-server提供的模拟数据时,返回结果并非预期的JSON数据,而是Vite开发服务器的入口HTML文档。
控制台输出
clients: <!doctype html> <html lang="en"> <head> <script type="module"> import RefreshRuntime from "/@react-refresh" RefreshRuntime.injectIntoGlobalHook(window) window.$RefreshReg$ = () => {} window.$RefreshSig$ = () => (type) => type window.__vite_plugin_react_preamble_installed__ = true </script> <script type="module" src="/@vite/client"></script> <meta charset="UTF-8" /> <link rel="icon" type="image/svg+xml" href="/vite.svg" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>FlowSwift POC</title> </head> <body> <div id="root"></div> <script type="module" src="/src/main.tsx?t=1716566140428"></script> </body> </html>
相关代码文件
Hook文件(clientServiceHooks.ts)
import { useQuery } from "@tanstack/react-query"; import { api, queryClient } from "@/services/api"; import { ClientType } from "./types"; const endpoint = "client"; export const baseClientQueryKey = "client"; export const useGetClients = () => useQuery<ClientType[]>({ queryKey: [baseClientQueryKey], queryFn: async () => api.get(endpoint), });
API配置文件(api.ts)
import axios from 'axios'; import { QueryClient} from '@tanstack/react-query'; export const queryClient = new QueryClient(); export const baseURL ='http://localhost:5174'; export const baseHeaders = {}; export const api = axios.create({ baseURL }); api.interceptors.response.use( function (response) { return response.data }, function (error) { return Promise.reject(error); } )
Mock环境API配置文件(mock/index.ts)
import axios from 'axios'; import { QueryClient} from '@tanstack/react-query'; export const queryClient = new QueryClient(); export const baseURL = Boolean(import.meta.env.VITE_MOCK) ? 'http://localhost:5174' : 'http://localhost:8098'; export const baseHeaders = {}; export const api = axios.create({ baseURL }); api.interceptors.response.use( function (response) { return response.data }, function (error) { return Promise.reject(error); } )
json-server启动文件(mock/index.cjs)
const jsonServer = require("json-server"); const clientMock = require("./data/clientMock.json"); const serverPort = 5174; /** * * @param {MockServerConfig} config * * * @throws {Error} */ export const startMockServer = () => { try { const mockServer = jsonServer.create(); /* Add mock data entities here */ const router = jsonServer.router({ client: clientMock, }); const middleware = jsonServer.defaults(); mockServer.use(middleware); mockServer.use( jsonServer.rewriter({ "/*": "/$1", "/client/:clientId": "/client?clientId=:clientId", }) ); mockServer.use(router); mockServer.listen(serverPort, () => { console.log(`JSON Server is running on http://localhost:${serverPort}/`); }); } catch (error) { if (error instanceof Error) { console.log(error.message); } else { console.log("createMockServer failed", error); } } }; startMockServer();
模拟数据文件(mock/data/clientMock.json)
[ { "clientId": "123", "clientName": "Client 1", "clientStatus": "LEAD" }, { "clientId": "456", "clientName": "Client 2", "clientStatus": "CURRENT" }, { "clientId": "789", "clientName": "Client 3", "clientStatus": "COLD" } ]
组件调用代码(ClientsTable.tsx)
import { useGetClients } from "@/services/client/clientServiceHooks"; export const ClientsTable = () => { const { data: clients } = useGetClients(); console.log("clients: ", clients); return <div>ClientsTable</div>; };
排查与解决步骤
1. 确认json-server是否正常启动
检查启动终端是否输出JSON Server is running on http://localhost:5174/。如果没有,执行启动脚本:
- 在package.json中添加脚本:
"mock": "node mock/index.cjs" - 运行
npm run mock启动mock服务器
2. 检查端口占用情况
确保5174端口被json-server占用,而非Vite开发服务器:
- Windows:执行
netstat -ano | findstr :5174 - Mac/Linux:执行
lsof -i :5174
如果端口被Vite占用,修改Vite配置端口(如改回5173)或json-server端口(如改为5175)
3. 统一API配置逻辑
当前Hook导入的是固定baseURL的@/services/api,而非mock环境的API配置,导致环境切换失效。修改api.ts合并环境判断逻辑:
import axios from 'axios'; import { QueryClient} from '@tanstack/react-query'; export const queryClient = new QueryClient(); // 根据环境变量自动切换baseURL export const baseURL = Boolean(import.meta.env.VITE_MOCK) ? 'http://localhost:5174' : 'http://localhost:8098'; export const baseHeaders = {}; export const api = axios.create({ baseURL }); api.interceptors.response.use( function (response) { return response.data }, function (error) { return Promise.reject(error); } )
删除mock目录下重复的API配置文件,确保所有请求使用统一配置。
4. 验证请求地址
在浏览器开发者工具的Network面板中,查看请求的完整URL是否为http://localhost:5174/client。若地址错误,检查baseURL和endpoint拼接逻辑。
5. 测试json-server路由
直接在浏览器访问http://localhost:5174/client,确认返回的是预期的JSON数组。若返回HTML,说明json-server未正常启动或端口配置错误。
内容的提问来源于stack exchange,提问作者Jon Jackson
相关产品推荐
相关产品推荐

