add a home page before dash. it's use to auto navigate to proxy service.

This commit is contained in:
alex liu 2023-04-19 22:25:08 +08:00
parent 0214b974dd
commit f9f1da5069
9 changed files with 4163 additions and 1 deletions

View File

@ -6,6 +6,23 @@
[README](README.md) | [中文文档](README_zh.md)
> This version adds a navigation page that automatically reads TCP proxy on the basis of the original Dashboard. The page uses the rarely used empty attributes `group_key` and `group` to pass the direct connection address and navigation image. For non-HTTP links, this content does not need to be configured (such as SSH), in which case the navigation page will ignore the proxy item. The navigation icon can be configured using the group field and can be in BASE64 format or a linkable URL. Here is an example configuration:
```
[Nextcloud]
type = tcp
local_ip = 127.0.0.1
local_port = 3000
remote_port = 6000
group = data:image/svg+xml;base64,PHN2ZyB0PSIxNjgxOTA4ODAyODYxIiBjbGFzcz0iaWNvbiIgdmlld0JveD0iMCAwIDEwMjQgMTAyNCIgdmVyc2lvbj0iMS4xIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHAtaWQ9IjEyMDgiIHdpZHRoPSIyMDAiIGhlaWdodD0iMjAwIj48cGF0aCBkPSJNMTAyLjQgMTAyLjRtMzA3LjIgMGwyMDQuOCAwcTMwNy4yIDAgMzA3LjIgMzA3LjJsMCAyMDQuOHEwIDMwNy4yLTMwNy4yIDMwNy4ybC0yMDQuOCAwcS0zMDcuMiAwLTMwNy4yLTMwNy4ybDAtMjA0LjhxMC0zMDcuMiAzMDcuMi0zMDcuMloiIGZpbGw9IiM1MENDQ0MiIHAtaWQ9IjEyMDkiPjwvcGF0aD48cGF0aCBkPSJNNTEzLjcwNDk2IDMwNy4yQzU4OS4xMTIzMiAzMDcuMiA2NTAuMjQgMzY4LjMzMjggNjUwLjI0IDQ0My43MzUwNGM3NS40MDczNiAwIDEzNi41MzUwNCA2MS4xMjc2OCAxMzYuNTM1MDQgMTM2LjUyOTkyIDAgNzUuNDA3MzYtNjEuMTMyOCAxMzYuNTM1MDQtMTM2LjUzNTA0IDEzNi41MzUwNEgzNzcuMTc1MDRDMzAxLjc2NzY4IDcxNi44IDI0MC42NCA2NTUuNjY3MiAyNDAuNjQgNTgwLjI2NDk2YzAtNzUuNDAyMjQgNjEuMTMyOC0xMzYuNTI5OTIgMTM2LjUzNTA0LTEzNi41Mjk5MmwwLjAxNTM2LTIuMjU3OTJDMzc4LjM5ODcyIDM2Ny4xMDQgNDM5LjA1NTM2IDMwNy4yIDUxMy43MDQ5NiAzMDcuMnoiIGZpbGw9IiNGRkZGRkYiIGZpbGwtb3BhY2l0eT0iLjgiIHAtaWQ9IjEyMTAiPjwvcGF0aD48L3N2Zz4=
group_key = https://nextcloud.domain.com
```
And it looks like:
![image](https://raw.githubusercontent.com/synebula/frp-with-navigation-page/dev/doc/pic/navigation.png)
<h3 align="center">Gold Sponsors</h3>
<!--gold sponsors start-->
<p align="center">

View File

@ -7,6 +7,22 @@
frp 是一个专注于内网穿透的高性能的反向代理应用,支持 TCP、UDP、HTTP、HTTPS 等多种协议。可以将内网服务以安全、便捷的方式通过具有公网 IP 节点的中转暴露到公网。
> 该版本在原版Dashboard基础上增加了一个自动读取TCP代理的导航页面。 该页面利用了不常用的空置属性`group_key`和`group`来传递直连地址和导航图片对于非HTTP链接可以可以不用配置这部分内容(如SSH),这种情况下导航页面会忽略该代理项。使用`group`字段配置导航图标可以是BASE64格式也可以是可链接地URL配置示例
```
[Nextcloud]
type = tcp
local_ip = 127.0.0.1
local_port = 3000
remote_port = 6000
group = data:image/svg+xml;base64,PHN2ZyB0PSIxNjgxOTA4ODAyODYxIiBjbGFzcz0iaWNvbiIgdmlld0JveD0iMCAwIDEwMjQgMTAyNCIgdmVyc2lvbj0iMS4xIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHAtaWQ9IjEyMDgiIHdpZHRoPSIyMDAiIGhlaWdodD0iMjAwIj48cGF0aCBkPSJNMTAyLjQgMTAyLjRtMzA3LjIgMGwyMDQuOCAwcTMwNy4yIDAgMzA3LjIgMzA3LjJsMCAyMDQuOHEwIDMwNy4yLTMwNy4yIDMwNy4ybC0yMDQuOCAwcS0zMDcuMiAwLTMwNy4yLTMwNy4ybDAtMjA0LjhxMC0zMDcuMiAzMDcuMi0zMDcuMloiIGZpbGw9IiM1MENDQ0MiIHAtaWQ9IjEyMDkiPjwvcGF0aD48cGF0aCBkPSJNNTEzLjcwNDk2IDMwNy4yQzU4OS4xMTIzMiAzMDcuMiA2NTAuMjQgMzY4LjMzMjggNjUwLjI0IDQ0My43MzUwNGM3NS40MDczNiAwIDEzNi41MzUwNCA2MS4xMjc2OCAxMzYuNTM1MDQgMTM2LjUyOTkyIDAgNzUuNDA3MzYtNjEuMTMyOCAxMzYuNTM1MDQtMTM2LjUzNTA0IDEzNi41MzUwNEgzNzcuMTc1MDRDMzAxLjc2NzY4IDcxNi44IDI0MC42NCA2NTUuNjY3MiAyNDAuNjQgNTgwLjI2NDk2YzAtNzUuNDAyMjQgNjEuMTMyOC0xMzYuNTI5OTIgMTM2LjUzNTA0LTEzNi41Mjk5MmwwLjAxNTM2LTIuMjU3OTJDMzc4LjM5ODcyIDM2Ny4xMDQgNDM5LjA1NTM2IDMwNy4yIDUxMy43MDQ5NiAzMDcuMnoiIGZpbGw9IiNGRkZGRkYiIGZpbGwtb3BhY2l0eT0iLjgiIHAtaWQ9IjEyMTAiPjwvcGF0aD48L3N2Zz4=
group_key = https://nextcloud.domain.com
```
导航效果图:
![image](https://raw.githubusercontent.com/synebula/frp-with-navigation-page/dev/doc/pic/navigation.png)
<h3 align="center">Gold Sponsors</h3>
<!--gold sponsors start-->
<p align="center">

BIN
doc/pic/navigation.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 424 KiB

View File

@ -3,6 +3,7 @@
<head>
<meta charset="utf-8">
<meta name="viewport" content="user-scalable=0,width=device-width, initial-scale=1.0">
<title>frps dashboard</title>
</head>

104
web/frps/src/Home.vue Normal file
View File

@ -0,0 +1,104 @@
<template>
<div id="container">
<div id="wrap">
<div id="top">
<div id="logo">
<!--<img class="logo"-->
<!-- src="img/logo.png"-->
<!--/>-->
<!--如果需要自定义logo图片,使用上面这段代码,并删除下面这段代码,图片位置应放在img下的logo.png-->
<router-link to="/overview">
<img
class="logo"
src="data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBzdGFuZGFsb25lPSJubyI/PjwhRE9DVFlQRSBzdmcgUFVCTElDICItLy9XM0MvL0RURCBTVkcgMS4xLy9FTiIgImh0dHA6Ly93d3cudzMub3JnL0dyYXBoaWNzL1NWRy8xLjEvRFREL3N2ZzExLmR0ZCI+PHN2ZyB0PSIxNjgxODk0Mjk2MzM3IiBjbGFzcz0iaWNvbiIgdmlld0JveD0iMCAwIDEwMjQgMTAyNCIgdmVyc2lvbj0iMS4xIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHAtaWQ9IjI2NjEiIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB3aWR0aD0iMjAwIiBoZWlnaHQ9IjIwMCI+PHBhdGggZD0iTTc4NS4wNjY2NjcgODUzLjMzMzMzM0gyMzguOTMzMzMzYy0xMzMuMTIgMC0yMzguOTMzMzMzLTEwNS44MTMzMzMtMjM4LjkzMzMzMy0yMzguOTMzMzMzIDAtMTA1LjgxMzMzMyA3MS42OC0xOTcuOTczMzMzIDE3MC42NjY2NjctMjI4LjY5MzMzMyA2LjgyNjY2Ny03MS42OCA3MS42OC0xMjkuNzA2NjY3IDE0My4zNi0xMjkuNzA2NjY3aDYuODI2NjY2YzIwLjQ4IDAgNDAuOTYgMy40MTMzMzMgNjEuNDQgMTMuNjUzMzMzQzQyNi42NjY2NjcgMjA4LjIxMzMzMyA0OTguMzQ2NjY3IDE3MC42NjY2NjcgNTczLjQ0IDE3MC42NjY2NjdoNi44MjY2NjdjMTE5LjQ2NjY2NyAwIDIyMS44NjY2NjcgODguNzQ2NjY3IDIzNS41MiAyMDguMjEzMzMzIDExNi4wNTMzMzMgMTcuMDY2NjY3IDIwOC4yMTMzMzMgMTE2LjA1MzMzMyAyMDguMjEzMzMzIDIzNS41MiAwIDEzMy4xMi0xMDUuODEzMzMzIDIzOC45MzMzMzMtMjM4LjkzMzMzMyAyMzguOTMzMzMzek0zMTcuNDQgMjkwLjEzMzMzM0MyNTYgMjkwLjEzMzMzMyAyMDQuOCAzMzcuOTIgMjA0LjggMzk5LjM2YzAgNi44MjY2NjctNi44MjY2NjcgMTMuNjUzMzMzLTEzLjY1MzMzMyAxNy4wNjY2NjctOTIuMTYgMjAuNDgtMTU3LjAxMzMzMyAxMDIuNC0xNTcuMDEzMzM0IDE5Ny45NzMzMzMgMCAxMTIuNjQgOTIuMTYgMjA0LjggMjA0LjggMjA0LjhoNTQ2LjEzMzMzNGMxMTIuNjQgMCAyMDQuOC05Mi4xNiAyMDQuOC0yMDQuOCAwLTEwNS44MTMzMzMtODEuOTItMTk3Ljk3MzMzMy0xOTEuMTQ2NjY3LTIwNC44LTYuODI2NjY3IDAtMTMuNjUzMzMzLTYuODI2NjY3LTE3LjA2NjY2Ny0xNy4wNjY2NjdDNzc4LjI0IDI4Ni43MiA2ODYuMDggMjA0LjggNTgwLjI2NjY2NyAyMDQuOGgtMy40MTMzMzRsLTMuNDEzMzMzLTE3LjA2NjY2N1YyMDQuOGMtNjguMjY2NjY3IDAtMTI5LjcwNjY2NyAzNC4xMzMzMzMtMTY3LjI1MzMzMyA5NS41NzMzMzMtNi44MjY2NjcgNi44MjY2NjctMTcuMDY2NjY3IDEwLjI0LTIzLjg5MzMzNCA2LjgyNjY2Ny0xNy4wNjY2NjctMTAuMjQtMzcuNTQ2NjY3LTE3LjA2NjY2Ny01OC4wMjY2NjYtMTcuMDY2NjY3aC0zLjQxMzMzNC0zLjQxMzMzM3oiIGZpbGw9IiNmZmZmZmYiIHAtaWQ9IjI2NjIiPjwvcGF0aD48L3N2Zz4="
/>
</router-link>
<p></p>
<div class="headline">
<h1>Welcome</h1>
</div>
<div class="" id="kg-btn">
<input class="tgl tgl-flip" id="qieh" type="checkbox" />
<label
class="tgl-btn"
data-tg-off="PROXY"
data-tg-on="DIRECT"
for="qieh"
@click="toggleProxy"
></label>
</div>
</div>
</div>
<div id="main">
<div class="app animated fadeInLeft" id="app">
<ul>
<li v-for="p in proxies">
<a :href="isProxy ? p.proxyUrl : p.directUrl" target="_blank">
<img class="shake" width="128" height="128" :src="p.image" />
<strong>{{ p.name }}</strong></a
>
</li>
</ul>
</div>
</div>
</div>
<div id="footer">
<div class="footer-contents">
<div class="links">
<div class="line">
<a href="/">FRP Home</a>&nbsp;&nbsp;&nbsp;
<span class="footer-link-separator"></span>&nbsp;&nbsp;&nbsp;
<span class="copyright">@</span>
</div>
</div>
</div>
</div>
</div>
</template>
<script setup lang="ts">
import { ref } from 'vue'
class Item {
name: string
image: string
directUrl: string
proxyUrl: string
/**
*
*/
constructor(proxy: any, host: string) {
this.name = proxy.name
this.image = proxy.conf.group
this.directUrl = proxy.conf.group_key
this.proxyUrl = `${host}:${proxy.conf.remote_port}`
}
}
let proxies = ref<Item[]>([])
let isProxy = ref<Boolean>(true)
const protocal = window.location.protocol
const host = window.location.hostname
const fetchData = () => {
fetch('../api/proxy/tcp', { credentials: 'include' })
.then((res) => {
return res.json()
})
.then((json) => {
for (let proxy of json.proxies) {
if (proxy != null && proxy.conf.group != '')
proxies.value.push(new Item(proxy, `${protocal}//${host}`))
}
})
}
fetchData()
const toggleProxy = () => {
isProxy.value = !isProxy.value
}
</script>
<style scoped>
@import url('assets/style.css');
</style>

31
web/frps/src/Preload.vue Normal file
View File

@ -0,0 +1,31 @@
<template>
<div v-if="isHome">
<router-view />
</div>
<div v-else>
<App />
</div>
</template>
<script lang="ts">
import App from './App.vue'
export default {
components: {
App,
},
data() {
return {
isHome: false,
}
},
mounted() {
this.isHome = document.location.hash == '#/'
},
watch: {
$route(to, from) {
this.isHome = to.path == '/'
},
},
}
</script>

File diff suppressed because it is too large Load Diff

View File

@ -1,7 +1,7 @@
import { createApp } from 'vue'
import 'element-plus/dist/index.css'
import 'element-plus/theme-chalk/dark/css-vars.css'
import App from './App.vue'
import App from './Preload.vue'
import router from './router'
import './assets/custom.css'

View File

@ -1,4 +1,5 @@
import { createRouter, createWebHashHistory } from 'vue-router'
import Home from '../Home.vue'
import ServerOverview from '../components/ServerOverview.vue'
import ProxiesTCP from '../components/ProxiesTCP.vue'
import ProxiesUDP from '../components/ProxiesUDP.vue'
@ -12,6 +13,11 @@ const router = createRouter({
routes: [
{
path: '/',
name: 'Home',
component: Home,
},
{
path: '/overview',
name: 'ServerOverview',
component: ServerOverview,
},