-
Notifications
You must be signed in to change notification settings - Fork 15
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
3 changed files
with
299 additions
and
5 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,238 @@ | ||
# 3实现搜索结果 | ||
|
||
## 问ChatGPT的问题 | ||
|
||
现在要用 Next.js 与 chakra.ui 建`whois`站,根据如下描述与已有代码,写出`src/pages/whois/[domain].js`的代码,使用js自带fetch实现 | ||
|
||
### 用户案例 | ||
|
||
假设用户想要一个带 gantrol 的域名,比较想要 gantrol.com,用户主要想得到什么情报呢? | ||
|
||
- 这个域名的信息,最主要的是,有没有被注册、是否能买到 | ||
- 有没有相关域名可以注册 | ||
|
||
### 外部api | ||
|
||
数据的结构决定代码的结构,必须了解数据,才能写出符合要求的代码。 | ||
|
||
```markdown | ||
https://whois.freeaiapi.xyz/?name=${name}&suffix=${suffix} | ||
``` | ||
|
||
示例:查询 gantrol.com,被拆分为 whois.freeaiapi.xyz/?name=gantrol&suffix=com | ||
|
||
请求的返回分为两种,不清楚怎么调用接口的同学也先别急,可以用<https://whois.gantrol.com> 确认一下。 | ||
|
||
- available = true | ||
|
||
```json | ||
{ | ||
"status": "ok", | ||
"name": "gantrol", | ||
"suffix": "com", | ||
"domain": "gantrol.com", | ||
"creation_datetime": "2020-10-29T04:08:52Z", | ||
"expiry_datetime": "2024-10-29T04:08:52Z", | ||
"available": false, | ||
"info": " Domain Name: GANTROL.COM\r\n Registry Domain ID: 2568931463_DOMAIN_COM-VRSN\r\n Registrar WHOIS Server: whois.paycenter.com.cn\r\n 《省略几百词》 .\r\n" | ||
} | ||
``` | ||
|
||
- available = false | ||
|
||
```json | ||
{ | ||
"status": "ok", | ||
"name": "gantrol", | ||
"suffix": "org", | ||
"domain": "gantrol.org", | ||
"creation_datetime": "", | ||
"expiry_datetime": "", | ||
"available": true, | ||
"info": "Domain not found.\r\n>>> Last update of WHOIS database: 2023-12-05T08:58:08Z <<<\r\n\r\nTerms of Use:..《省略几百词》.\r\n" | ||
} | ||
``` | ||
|
||
### 基本界面设计 | ||
|
||
- 主页主体是Google极简风格的搜索框,商标位置先用文字“域名搜索”替代 | ||
|
||
- 用户搜索`gantrol.com` 后,网站跳转到`/whois/gantrol.com`,然后页面顶端是搜索框,其下是具体的域名信息 | ||
|
||
- "available": true, | ||
|
||
### 已有代码 | ||
|
||
#### index.js | ||
|
||
```jsx | ||
import {Flex, Heading, IconButton, Input} from "@chakra-ui/react"; | ||
import {SearchIcon} from "@chakra-ui/icons"; | ||
import {useState} from "react"; | ||
import {useRouter} from "next/router"; | ||
|
||
export default function Home() { | ||
const [domain, setDomain] = useState(''); | ||
const router = useRouter(); | ||
|
||
const handleSearch = () => { | ||
if (domain) { | ||
router.push(`/whois/${domain}`); | ||
} | ||
}; | ||
|
||
return ( | ||
<Flex | ||
direction="column" | ||
justify="center" | ||
align="center" | ||
height="100vh" | ||
> | ||
<Heading mb={4}>域名搜索</Heading> | ||
<Flex | ||
justify="center" | ||
align="center" | ||
// 添加间距 | ||
gap="2" | ||
> | ||
<Input | ||
placeholder="输入域名" | ||
value={domain} | ||
// 当输入框的值改变时,更改 domain 的值 | ||
onChange={(e) => setDomain(e.target.value)} | ||
// 基础屏幕尺寸下宽度为 90%(适用于较小屏幕的移动设备),以及中等屏幕尺寸(如平板或小型桌面显示器)下的宽度为 400px | ||
width={{base: "90%", md: "400px"}} | ||
/> | ||
<IconButton | ||
icon={<SearchIcon/>} | ||
// 为按钮添加点击事件 | ||
onClick={handleSearch} | ||
/> | ||
</Flex> | ||
</Flex> | ||
); | ||
} | ||
|
||
|
||
``` | ||
|
||
### `src/pages/api/whois.js` | ||
|
||
```javascript | ||
// 导入 Next.js 的 API 路由支持 | ||
import { NextApiRequest, NextApiResponse } from "next"; | ||
|
||
// 处理 API 请求的函数 | ||
export default async function handler(req, res) { | ||
// 从查询字符串中获取域名和后缀 | ||
const { domain } = req.query; | ||
|
||
// 检查是否提供了域名和后缀 | ||
if (!domain) { | ||
return res.status(400).json({ error: "缺少必要的参数:domain" }); | ||
} | ||
|
||
// 解析域名和后缀 | ||
const [name, suffix] = domain.split("."); | ||
|
||
// 构建外部 API 请求的 URL | ||
const apiUrl = `https://whois.freeaiapi.xyz/?name=${name}&suffix=${suffix}`; | ||
|
||
try { | ||
// 使用 fetch 发送请求到外部 API | ||
const response = await fetch(apiUrl); | ||
const data = await response.json(); | ||
|
||
// 将获取到的信息返回给客户端 | ||
res.status(200).json(data); | ||
} catch (error) { | ||
// 处理可能发生的错误 | ||
res.status(500).json({ error: "服务器错误,无法获取域名信息" }); | ||
} | ||
} | ||
``` | ||
|
||
|
||
## GPT 回答示例 | ||
|
||
> 注:回答不唯一 | ||
https://chat.openai.com/share/61630b22-ac41-4dac-ae29-0067e5a4b0de | ||
|
||
基于您提供的用户案例、外部 API 信息、基本界面设计,以及已有的 `index.js` 和 `src/pages/api/whois.js` 代码,我们可以编写 `src/pages/whois/[domain].js` 文件。这个文件将用于显示用户查询的域名信息。 | ||
|
||
代码将包括以下几个部分: | ||
|
||
1. 导入必要的模块和组件。 | ||
2. 创建一个 React 组件,它将通过 Next.js 的 `useRouter` 钩子获取动态路由参数(即域名)。 | ||
3. 使用 `useEffect` 钩子和 `fetch` 函数调用自定义的 `/api/whois` 接口以获取域名信息。 | ||
4. 根据获取的数据,渲染域名信息。 | ||
5. 处理加载状态和可能出现的错误。 | ||
|
||
接下来是具体的实现代码: | ||
|
||
```jsx | ||
import { Box, Flex, Text, Spinner, Alert, AlertIcon } from "@chakra-ui/react"; | ||
import { useRouter } from "next/router"; | ||
import { useEffect, useState } from "react"; | ||
|
||
export default function Whois() { | ||
const router = useRouter(); | ||
const { domain } = router.query; | ||
const [loading, setLoading] = useState(false); | ||
const [error, setError] = useState(null); | ||
const [domainInfo, setDomainInfo] = useState(null); | ||
|
||
useEffect(() => { | ||
if (domain) { | ||
setLoading(true); | ||
fetch(`/api/whois?domain=${domain}`) | ||
.then(res => res.json()) | ||
.then(data => { | ||
setDomainInfo(data); | ||
setLoading(false); | ||
}) | ||
.catch(error => { | ||
console.error("Error fetching domain info:", error); | ||
setError("无法获取域名信息,请稍后重试。"); | ||
setLoading(false); | ||
}); | ||
} | ||
}, [domain]); | ||
|
||
if (loading) { | ||
return <Spinner />; | ||
} | ||
|
||
if (error) { | ||
return ( | ||
<Alert status="error"> | ||
<AlertIcon /> | ||
{error} | ||
</Alert> | ||
); | ||
} | ||
|
||
return ( | ||
<Flex direction="column" align="center" p={5}> | ||
<Text fontSize="xl" mb={2}>域名信息查询结果</Text> | ||
{domainInfo && ( | ||
<Box p={4} borderWidth="1px" borderRadius="lg"> | ||
<Text><b>域名:</b> {domainInfo.domain}</Text> | ||
<Text><b>是否可注册:</b> {domainInfo.available ? "是" : "否"}</Text> | ||
{domainInfo.creation_datetime && ( | ||
<Text><b>创建时间:</b> {domainInfo.creation_datetime}</Text> | ||
)} | ||
{domainInfo.expiry_datetime && ( | ||
<Text><b>过期时间:</b> {domainInfo.expiry_datetime}</Text> | ||
)} | ||
<Text><b>详细信息:</b></Text> | ||
<Text whiteSpace="pre-wrap">{domainInfo.info}</Text> | ||
</Box> | ||
)} | ||
</Flex> | ||
); | ||
} | ||
``` | ||
|
||
在这段代码中,我们首先从路由中获取 `domain` 参数,然后使用 `useEffect` 钩子在组件加载时发送请求到我们的 API 接口。请求成功时,我们将数据存储在状态变量中,并在页面上显示它。同时,我们也处理了加载状态和可能发生的错误。 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,61 @@ | ||
import { Box, Flex, Text, Spinner, Alert, AlertIcon } from "@chakra-ui/react"; | ||
import { useRouter } from "next/router"; | ||
import { useEffect, useState } from "react"; | ||
|
||
export default function Whois() { | ||
const router = useRouter(); | ||
const { domain } = router.query; | ||
const [loading, setLoading] = useState(false); | ||
const [error, setError] = useState(null); | ||
const [domainInfo, setDomainInfo] = useState(null); | ||
|
||
useEffect(() => { | ||
if (domain) { | ||
setLoading(true); | ||
fetch(`/api/whois?domain=${domain}`) | ||
.then(res => res.json()) | ||
.then(data => { | ||
setDomainInfo(data); | ||
setLoading(false); | ||
}) | ||
.catch(error => { | ||
console.error("Error fetching domain info:", error); | ||
setError("无法获取域名信息,请稍后重试。"); | ||
setLoading(false); | ||
}); | ||
} | ||
}, [domain]); | ||
|
||
if (loading) { | ||
return <Spinner />; | ||
} | ||
|
||
if (error) { | ||
return ( | ||
<Alert status="error"> | ||
<AlertIcon /> | ||
{error} | ||
</Alert> | ||
); | ||
} | ||
|
||
return ( | ||
<div>假装有个结果页</div> | ||
<Flex direction="column" align="center" p={5}> | ||
<Text fontSize="xl" mb={2}>域名信息查询结果</Text> | ||
{domainInfo && ( | ||
<Box p={4} borderWidth="1px" borderRadius="lg"> | ||
<Text><b>域名:</b> {domainInfo.domain}</Text> | ||
<Text><b>是否可注册:</b> {domainInfo.available ? "是" : "否"}</Text> | ||
{domainInfo.creation_datetime && ( | ||
<Text><b>创建时间:</b> {domainInfo.creation_datetime}</Text> | ||
)} | ||
{domainInfo.expiry_datetime && ( | ||
<Text><b>过期时间:</b> {domainInfo.expiry_datetime}</Text> | ||
)} | ||
<Text><b>详细信息:</b></Text> | ||
<Text whiteSpace="pre-wrap">{domainInfo.info}</Text> | ||
</Box> | ||
)} | ||
</Flex> | ||
); | ||
} |