如何使用NextJS + TypeScript解析URL中的JSON并展示信息?
嗨,我明白你现在的处境——四处调研没找到清晰方向,能搞定本地JSON但远程的就卡壳了,还要对接Shopify API做仪表盘对吧?我给你几个实用的示例和思路,应该能帮到你:
从远程URL获取JSON + Shopify API客户数据的Next.js/TypeScript示例
一、基础远程JSON获取(以http://time.jsontest.com/为例)
先澄清一点:useRouter主要是用来处理路由导航的,和远程数据获取无关哦~远程JSON直接用fetch就能搞定,下面分Next.js常用的两种路由方案给你示例:
1. 客户端组件方式(Next.js 13+ App Router)
如果是在交互型的客户端组件里获取数据,用useEffect结合fetch即可:
'use client'; import { useState, useEffect } from 'react'; // 定义TypeScript类型,让数据更清晰 interface TimeData { time: string; milliseconds_since_epoch: number; date: string; } export default function RemoteJsonDemo() { const [data, setData] = useState<TimeData | null>(null); const [loading, setLoading] = useState(true); const [error, setError] = useState<string | null>(null); useEffect(() => { const fetchRemoteData = async () => { try { const res = await fetch('http://time.jsontest.com/'); if (!res.ok) throw new Error(`请求失败,状态码: ${res.status}`); const jsonData = await res.json(); setData(jsonData); } catch (err) { setError(err instanceof Error ? err.message : '未知错误'); } finally { setLoading(false); } }; fetchRemoteData(); }, []); if (loading) return <div>加载中...</div>; if (error) return <div>出错了: {error}</div>; return ( <div> <h3>远程时间数据</h3> <p>当前时间: {data?.time}</p> <p>日期: {data?.date}</p> <p>时间戳: {data?.milliseconds_since_epoch}</p> </div> ); }
2. 服务器组件方式(Next.js 13+ App Router)
服务器组件可以直接异步获取数据,不需要useEffect,适合不需要交互的静态/半静态页面,还能避免客户端请求的跨域问题:
// 不需要加'use client'标记 interface TimeData { time: string; milliseconds_since_epoch: number; date: string; } export default async function ServerSideRemoteJson() { try { const res = await fetch('http://time.jsontest.com/', { next: { revalidate: 60 } // 60秒缓存数据,减少重复请求 }); if (!res.ok) throw new Error(`请求失败,状态码: ${res.status}`); const data: TimeData = await res.json(); return ( <div> <h3>服务器端获取的时间数据</h3> <p>当前时间: {data.time}</p> <p>日期: {data.date}</p> <p>时间戳: {data.milliseconds_since_epoch}</p> </div> ); } catch (err) { return <div>服务器端获取数据失败: {err instanceof Error ? err.message : '未知错误'}</div>; } }
二、对接Shopify API获取客户数据(仪表盘开发)
关键提醒:Shopify API的密钥、令牌绝对不能暴露在客户端,所有请求必须在服务器端发起(服务器组件、API路由或Server Actions都可以)。
1. 准备工作
先从Shopify后台拿到这两个关键信息:
- 商店域名(比如
your-shop.myshopify.com) - Admin API访问令牌(在Shopify Partners后台或商店应用设置里生成,需要开启
read_customers权限)
2. 服务器组件获取客户数据示例
// app/customers-dashboard/page.tsx // 定义Shopify客户数据的TypeScript接口 interface ShopifyCustomer { id: number; email: string; first_name: string | null; last_name: string | null; created_at: string; phone: string | null; // 按需添加更多字段,参考Shopify API文档 } interface ShopifyCustomersResponse { customers: ShopifyCustomer[]; } export default async function CustomersDashboard() { // 从环境变量读取敏感信息,不要硬编码! const shopDomain = process.env.SHOPIFY_SHOP_DOMAIN; const accessToken = process.env.SHOPIFY_ADMIN_API_TOKEN; if (!shopDomain || !accessToken) { return <div>请先配置Shopify环境变量</div>; } try { const res = await fetch(`https://${shopDomain}/admin/api/2024-07/customers.json`, { headers: { 'X-Shopify-Access-Token': accessToken, 'Content-Type': 'application/json' }, next: { revalidate: 300 } // 5分钟缓存数据,避免触发Shopify API速率限制 }); if (!res.ok) { const errorDetails = await res.json(); throw new Error(`Shopify API请求失败: ${errorDetails.errors?.message || res.statusText}`); } const response: ShopifyCustomersResponse = await res.json(); const customers = response.customers; return ( <div className="dashboard-container"> <h2>客户数据库</h2> <div className="customer-grid"> {customers.map(customer => ( <div key={customer.id} className="customer-card"> <h3>{customer.first_name} {customer.last_name}</h3> <p>邮箱: {customer.email}</p> {customer.phone && <p>电话: {customer.phone}</p>} <p>创建时间: {new Date(customer.created_at).toLocaleDateString()}</p> </div> ))} </div> </div> ); } catch (err) { return <div>获取客户数据失败: {err instanceof Error ? err.message : '未知错误'}</div>; } }
3. 环境变量配置
在项目根目录创建.env.local文件,添加:
SHOPIFY_SHOP_DOMAIN=your-shop.myshopify.com SHOPIFY_ADMIN_API_TOKEN=your-admin-api-access-token
4. 注意事项
- 确保你的Shopify应用已经申请了
read_customers权限 - Shopify API有速率限制,一定要加缓存(
next: { revalidate: ... })来避免被限流 - 如果需要实时更新客户数据,可以用Shopify Webhooks推送,而不是频繁轮询
三、TypeScript类型优化小技巧
为了避免类型错误,推荐用zod做运行时类型验证(可选,但能大幅提升代码健壮性):
import { z } from 'zod'; // 定义客户数据的验证规则 const ShopifyCustomerSchema = z.object({ id: z.number(), email: z.string().email(), first_name: z.string().nullable(), last_name: z.string().nullable(), created_at: z.string().datetime(), phone: z.string().nullable() }); const ShopifyCustomersResponseSchema = z.object({ customers: z.array(ShopifyCustomerSchema) }); // 在获取数据后验证 const response = await res.json(); const validatedData = ShopifyCustomersResponseSchema.parse(response); // 此时validatedData的类型会被自动推断,完全符合预期
内容的提问来源于stack exchange,提问作者Sabrina Reyes
相关产品推荐
相关产品推荐

