NextJS中使用useSWR Hook时XHR成功但变量undefined及JSON解析错误
问题排查与修正方案
报错根源定位
- 你当前
fetch配置了mode: 'no-cors',这种模式下跨域请求会返回浏览器屏蔽的不透明响应,哪怕Network面板能看到接口返回内容,前端JS层完全读不到响应体,拿到的是空内容 - 此时执行
res.json()直接触发JSON.parse: unexpected end of data报错,SWR捕获异常后,对应的数据变量自然一直是undefined - 你在请求头中添加的
"Access-Control-Allow-Origin": "*"没有实际作用:该响应头是服务端返回的CORS校验规则头,不属于前端可自定义的请求头范畴,no-cors模式下这类自定义头会被浏览器直接过滤 - 代码同时违反了React Hooks调用规则:
useSWR被写在普通业务函数updateDates内部,没有在React组件、以use开头的自定义Hook顶层调用,会导致SWR内部状态和组件渲染周期脱节,哪怕请求成功也没法正常同步数据
正确实现代码
// 按照自定义Hook规范命名,以use开头 function useUpdateDates(FromDate, ToDate) { // 移除no-cors配置,保证可以正常读取响应内容 // 跨域需要服务端配置允许前端域名的CORS规则,不能靠前端请求配置绕过 const fetcher = (url) => fetch(url).then(res => { if (!res.ok) throw new Error(`请求失败,状态码:${res.status}`) // 增加格式判断,避免空响应触发解析报错 const contentType = res.headers.get('content-type') if (!contentType?.includes('application/json')) throw new Error('接口未返回合法JSON格式') return res.json() }) // 把动态传入的日期参数拼接进请求URL,不要硬编码查询语句 const url = `http://example.com/test_db/system.sql?query=sqlD&from_date=${FromDate}&to_date=${ToDate}` // 调用useSWR获取数据,对返回值做重命名 const { data: data1, error } = useSWR(url, fetcher) return { data1, isLoading: !error && !data1, isError: error } } // 直接在NextJS页面组件内调用Hook function TestPage() { const { data1, isLoading, isError } = useUpdateDates("01/01/2018", "12/31/2019") if (isLoading) return <p>数据加载中...</p> if (isError) return <p>接口请求异常</p> return <pre>{JSON.stringify(data1, null, 2)}</pre> }
特殊场景处理方案
如果暂时无法协调服务端配置CORS规则,不要用no-cors模式直接请求外部接口,可以通过NextJS自带的API路由做请求中转:前端请求自己项目内的API路由,由Node.js层面调用外部接口获取数据,再转发给前端,从根源上规避跨域限制。
内容的提问来源于stack exchange,提问作者TheBetterJORT
相关产品推荐
相关产品推荐

