feat: 网站favicon获取
This commit is contained in:
@@ -0,0 +1,16 @@
|
||||
//统一管理咱们项目用户相关的接口
|
||||
import request from '@/utils/request'
|
||||
|
||||
import type {
|
||||
WebInfoReqData,
|
||||
getWebInfoResponseData
|
||||
} from './type'
|
||||
|
||||
//项目用户相关的请求地址
|
||||
|
||||
enum API {
|
||||
//获取网站信息
|
||||
WEBINFO = '/webinfo'
|
||||
}
|
||||
//获取ip
|
||||
export const fetchWebInfo = (data: WebInfoReqData) => request.get<any, getWebInfoResponseData>(API.WEBINFO + '/' + data.link)
|
||||
@@ -0,0 +1,18 @@
|
||||
import { ResponseData } from "../common"
|
||||
|
||||
export interface WebInfoReqData {
|
||||
link: string
|
||||
}
|
||||
|
||||
export interface WebInfo {
|
||||
link: string,
|
||||
logo: string,
|
||||
title: string,
|
||||
keywords: string,
|
||||
desc: string
|
||||
}
|
||||
|
||||
//响应格式
|
||||
export interface getWebInfoResponseData extends ResponseData {
|
||||
data: WebInfo
|
||||
}
|
||||
@@ -16,7 +16,7 @@ const info = reactive({
|
||||
<div class="flex flex-col mt-3 flex-1">
|
||||
<DetailHeader :title="info.title"></DetailHeader>
|
||||
|
||||
<div class="">
|
||||
<div class="p-4 rounded-2xl bg-white">
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -0,0 +1,105 @@
|
||||
<script setup lang="ts">
|
||||
import { ref, reactive } from 'vue'
|
||||
import DetailHeader from '@/components/Layout/DetailHeader/DetailHeader.vue'
|
||||
import { copy } from '@/utils/string'
|
||||
import { isUrl } from '@/utils/url'
|
||||
import { useToolsStore } from '@/store/modules/tools'
|
||||
import { ElMessage } from 'element-plus'
|
||||
const info = reactive({
|
||||
title: "网站favicon获取",
|
||||
})
|
||||
|
||||
//store
|
||||
const toolsStore = useToolsStore()
|
||||
|
||||
const searchUrl = ref()
|
||||
|
||||
const getWebInfo = async () => {
|
||||
try {
|
||||
if (isUrl(searchUrl.value)) {
|
||||
//有效的域名
|
||||
if (!searchUrl.value.includes('http://') && !searchUrl.value.includes('https://')) {
|
||||
searchUrl.value = 'http://' + searchUrl.value;
|
||||
}
|
||||
const urlObj = new URL(searchUrl.value)
|
||||
// webInfo.link = urlObj.hostname
|
||||
searchUrl.value = urlObj.hostname
|
||||
|
||||
await toolsStore.getWebInfo({
|
||||
link: searchUrl.value
|
||||
})
|
||||
} else {
|
||||
//无效的域名
|
||||
ElMessage({
|
||||
message: "无效的域名或地址",
|
||||
type: "error",
|
||||
duration: 1500
|
||||
})
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error fetching site info:', error);
|
||||
}
|
||||
};
|
||||
|
||||
//copy
|
||||
const copyRes = async (resStr: string) => {
|
||||
copy(resStr)
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="flex flex-col mt-3 flex-1">
|
||||
<DetailHeader :title="info.title"></DetailHeader>
|
||||
|
||||
<div class="p-4 rounded-2xl bg-white">
|
||||
<div>
|
||||
<el-input
|
||||
v-model="searchUrl"
|
||||
style="max-width: 600px"
|
||||
placeholder="请输入域名或地址"
|
||||
class="input-with-select"
|
||||
size="large"
|
||||
>
|
||||
<template #append>
|
||||
<el-button type="primary" @click="getWebInfo">获取</el-button>
|
||||
</template>
|
||||
</el-input>
|
||||
</div>
|
||||
<div>
|
||||
<ul>
|
||||
<li class="mt-3">
|
||||
<el-text>域名: </el-text>
|
||||
<el-link :href="'https://' + searchUrl" type="primary" target="_blank">{{ searchUrl }}</el-link>
|
||||
</li>
|
||||
<li class="mt-3 flex">
|
||||
<el-text>logo: </el-text>
|
||||
<div v-if="toolsStore.webInfo.logo" class="ml-2 flex items-center">
|
||||
<el-image :src="toolsStore.webInfo.logo" class="h-12"></el-image>
|
||||
<el-button class="ml-3" link type="primary">下载</el-button>
|
||||
</div>
|
||||
</li>
|
||||
<li class="mt-3 flex">
|
||||
<el-text >标题: </el-text>
|
||||
<div class="ml-2"></div>
|
||||
<el-text>{{ toolsStore.webInfo.title }}</el-text>
|
||||
</li>
|
||||
<li class="mt-3 flex">
|
||||
<el-text >关键词: </el-text>
|
||||
<div class="ml-2"></div>
|
||||
<el-text>{{ toolsStore.webInfo.keywords }}</el-text>
|
||||
</li>
|
||||
<li class="mt-3 flex">
|
||||
<el-text>描述: </el-text>
|
||||
<div class="ml-2"></div>
|
||||
<el-text>{{ toolsStore.webInfo.desc }}</el-text>
|
||||
<!-- <el-button>复制</el-button> -->
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
@@ -249,6 +249,16 @@ export const constantRoute = [
|
||||
description: '把文本转换成图片,生成长图,具有超多个性文字排版',
|
||||
}
|
||||
},
|
||||
{
|
||||
path: '/webInfo',
|
||||
component: () => import('@/components/WebInfo/WebInfo.vue'),
|
||||
name: 'webInfo',
|
||||
meta: {
|
||||
title: "网站favicon获取",
|
||||
keywords: '获取网站logo,获取网站icon,获取网站favicon,获取网站标题,获取网站关键词,获取网站描述',
|
||||
description: '获取网站logo、icon、favicon、标题、关键词、描述等信息',
|
||||
}
|
||||
},
|
||||
{
|
||||
path: '/about',
|
||||
component: () => import('@/components/Home/About.vue'),
|
||||
|
||||
@@ -4,7 +4,9 @@ import { getTools, getToolCate, getToolRecommend, toolCollect, getToolCollect }
|
||||
import { getIp } from '@/api/ip'
|
||||
import type { ToolsReqData, ToolsInfo, ToolCate, CollectReqData } from '@/api/tools/type'
|
||||
import type { IpReqData, IpInfo } from '@/api/ip/type'
|
||||
import type { WebInfo, WebInfoReqData } from '@/api/webinfo/type'
|
||||
import { useUserStore } from '@/store/modules/user'
|
||||
import { fetchWebInfo } from '@/api/webinfo'
|
||||
|
||||
export const useToolsStore = defineStore('tools', {
|
||||
//用来存放变量
|
||||
@@ -14,6 +16,7 @@ export const useToolsStore = defineStore('tools', {
|
||||
cates: [] as ToolCate[],
|
||||
recommends: [] as ToolsInfo[],
|
||||
ipData: {} as IpInfo,
|
||||
webInfo: {} as WebInfo,
|
||||
collect: [] as ToolsInfo[],
|
||||
collectIds: [] as number[],
|
||||
}),
|
||||
@@ -102,6 +105,16 @@ export const useToolsStore = defineStore('tools', {
|
||||
} else {
|
||||
return Promise.reject(new Error(result.message))
|
||||
}
|
||||
}
|
||||
},
|
||||
//获取网站信息
|
||||
async getWebInfo(data: WebInfoReqData) {
|
||||
const result: any = await fetchWebInfo(data)
|
||||
if (result.code == 200) {
|
||||
this.webInfo = result.data
|
||||
return result.message
|
||||
} else {
|
||||
return Promise.reject(new Error(result.message))
|
||||
}
|
||||
},
|
||||
}
|
||||
})
|
||||
@@ -0,0 +1,14 @@
|
||||
export function isUrl(str: string): boolean {
|
||||
// const urlPattern = new RegExp(
|
||||
// '^(https?:\\/\\/)?'+ // protocol
|
||||
// '((([a-z\\d]([a-z\\d-]*[a-z\\d])*)\\.)+[a-z]{2,}|'+ // domain name and extension
|
||||
// '((\\d{1,3}\\.){3}\\d{1,3}))'+ // OR ip (v4) address
|
||||
// '(\\:\\d+)?(\\/[-a-z\\d%_.~+]*)*'+ // port and path
|
||||
// '(\\?[;&a-z\\d%_.~+=-]*)?'+ // query string
|
||||
// '(\\#[-a-z\\d_]*)?$','i'); // fragment locator
|
||||
// return urlPattern.test(str);
|
||||
const urlPattern = new RegExp(
|
||||
'^(https?:\\/\\/)?'+ // protocol
|
||||
'((([a-z\\d]([a-z\\d-]*[a-z\\d])*)\\.)+[a-z]{2,})','i'); // fragment locator
|
||||
return urlPattern.test(str);
|
||||
}
|
||||
Reference in New Issue
Block a user