1.背景
最近一段时间AI和火爆,我也体验了一段时间的Bing、ChatGPT,感觉AI确实能在一定程度带来便捷,比如我常常用来查找资料、分析代码等。
后面因为网络原因账户被封禁了😂,也想过用开源工具搭建一个自己的ChatGPT镜像。
比如:
- https://github.com/Yidadaa/ChatGPT-Next-Web
- GitHub - Chanzhaoyu/chatgpt-web: 用 Express 和 Vue3 搭建的 ChatGPT 演示网页
- GitHub - mckaywrigley/chatbot-ui: An open source ChatGPT UI.
不过后面很多免费的AI工具、镜像网站如雨后春笋般用来,自己再搭建一个维护起来也麻烦(主要是想白嫖)
所以想着开发一个页面,收集众多免费好用的ChatGPT镜像站点,以及其他AI工具,并持续更新,方便查看和使用。
网址:Ai List - Timeless's博客 (timelessq.com)
主要用这些功能:
- 在线管理网站列表
- 网站排序,好用的排前边
- 检测是否可以访问,延迟低的也可以放前面
2.数据来源
首先一个问题是数据来源,总不能一个个收藏更新吧
好在Github上有大佬收集的数据:
3.管理网站列表
将上述2个Markdown里面的表格数据解析成JSON
[
{
"name": "ChatGPT",
"data": [
{
"url": "https://poe.com/",
"name": "Poe.com",
"free": true,
"recommend": true,
"lock": true,
"vpn": true
},
{
"url": "https://free.anzz.top/",
"name": "Anzz.top",
"free": true,
"recommend": true,
"vpn": true
},
...
]
},
{
"name": "办公",
"data": [...]
},
{
"name": "编程",
"data": [...]
}
}
由于直接是放在我的博客里面展示,那么可以直接用nuxt写一个单页,数据放在博客的后台在线管理就好了。
4.检测网站是否可用
这里用到的ajax请求网址来判断是否可以访问,并记录返回首字节的时间,可以算是访问的延迟吧。
不过有三个问题
第一个是:传统的ajax如axios、jQuery请求会有跨域限制,而fetch方法使用no-cors模式以避免CORS问题。
fetch('https://www.baidu.com/', {
mode: 'no-cors'
})
第二问题是:有些网站会超时,fetch不支持timeout设置,需要等待很久才能知道是否超时,而我们只需要判断大于10秒就认为不可访问了。
这里需要用到Promise.race,10秒的定时器和fetch请求,哪个先完成都停止计时,如果超时了还需要中断fetch的请求。
/**
* 检测网站的访问延迟
* @param {String} url 网站地址
* @returns {String}
*/
async function checkLatency (url) {
const start = performance.now()
let delay
try {
this.fetchLoading = true
await fetchUrl(url)
const end = performance.now()
delay = end - start
} catch (error) {
delay = 'unreachable'
}
return delay
}
/**
* 请求网站
* @param {String} url 网站地址
* @returns {Promise}
*/
function fetchUrl (url) {
const controller = new AbortController()
const signal = controller.signal
const timeoutPromise = (timeout) => {
return new Promise((resolve, reject) => {
setTimeout(() => {
reject(new Response('timeout', { status: 504, statusText: 'timeout' }))
controller.abort()
}, timeout)
})
}
const requestPromise = () => {
return fetch(url, {
mode: 'no-cors', // 使用no-cors模式以避免CORS问题
signal
})
}
return Promise.race([timeoutPromise(10000), requestPromise()])
}
第三个问题是:网站这么多,不能一进入页面就全部请求检测访问延迟吧。
所以用到IntersectionObserver判断列表元素是否出现在可视区域。
/**
* 监听Dom是否位于可视区域
* @param {Element} observerDom
* @param {Function} callback
*/
observeDom (observerDom, callback) {
const observer = new IntersectionObserver((entires) => {
if (entires[0].isIntersecting) {
callback && callback()
observer.disconnect()
}
})
observer.observe(observerDom)
}
5.网站排序
首先是可以通过推荐度排序,引入权重计算方式。
如果网站免费则权重+2,如果是稳定推荐的则权重+3,需要登录、查看公众号等有一定限制的权重-2,需要VPN国际网络的-5。
{
"url": "https://poe.com/", // 网站
"name": "Poe.com",
"free": true, // 是否免费
"recommend": true, // 是否推荐
"lock": true, // 是否有限制
"vpn": true // 是否需要国际网络
}
其次是可以通过访问延迟来排序,这个没啥好讲的啦,根据第四点的访问延迟数据就可以排序。
还没有评论,快来抢第一吧