1
0
mirror of https://github.com/nitezs/sub2clash.git synced 2024-12-23 20:24:42 -05:00

feat: 解析短链

This commit is contained in:
Nite07 2024-03-13 16:28:40 +08:00
parent 867da56f45
commit 1c5e17a4ab
4 changed files with 87 additions and 23 deletions

View File

@ -70,7 +70,30 @@ func ShortLinkGenHandler(c *gin.Context) {
c.String(200, hash) c.String(200, hash)
} }
func ShortLinkGetHandler(c *gin.Context) { func ShortLinkGetUrlHandler(c *gin.Context) {
var params validator.ShortLinkGetValidator
if err := c.ShouldBindQuery(&params); err != nil {
c.String(400, "参数错误: "+err.Error())
return
}
if strings.TrimSpace(params.Hash) == "" {
c.String(400, "参数错误")
return
}
var shortLink model.ShortLink
result := database.FindShortLinkByHash(params.Hash, &shortLink)
if result.Error != nil {
c.String(404, "未找到短链接")
return
}
if shortLink.Password != "" && shortLink.Password != params.Password {
c.String(403, "密码错误")
return
}
c.String(200, shortLink.Url)
}
func ShortLinkGetConfigHandler(c *gin.Context) {
// 获取动态路由 // 获取动态路由
hash := c.Param("hash") hash := c.Param("hash")
password := c.Query("password") password := c.Query("password")

View File

@ -53,14 +53,18 @@ func SetRoute(r *gin.Engine) {
handler.SubHandler(c) handler.SubHandler(c)
}, },
) )
r.POST( r.GET(
"/short", func(c *gin.Context) { "/s/:hash", func(c *gin.Context) {
handler.ShortLinkGenHandler(c) handler.ShortLinkGetConfigHandler(c)
}, },
) )
r.GET( r.GET(
"/s/:hash", func(c *gin.Context) { "/short", func(c *gin.Context) {
handler.ShortLinkGetHandler(c) handler.ShortLinkGetUrlHandler(c)
})
r.POST(
"/short", func(c *gin.Context) {
handler.ShortLinkGenHandler(c)
}, },
) )
r.PUT( r.PUT(

View File

@ -13,7 +13,6 @@
src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/js/bootstrap.bundle.min.js"></script> src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/js/bootstrap.bundle.min.js"></script>
<!-- Axios --> <!-- Axios -->
<script src="https://cdn.jsdelivr.net/npm/axios@latest/dist/axios.min.js"></script> <script src="https://cdn.jsdelivr.net/npm/axios@latest/dist/axios.min.js"></script>
<script src="./static/index.js"></script>
<style> <style>
.container { .container {
max-width: 800px; max-width: 800px;
@ -48,6 +47,7 @@
<label for="apiLink">解析链接:</label> <label for="apiLink">解析链接:</label>
<div class="input-group mb-2"> <div class="input-group mb-2">
<input class="form-control" id="urlInput" type="text" placeholder="通过生成的链接重新填写下方设置" /> <input class="form-control" id="urlInput" type="text" placeholder="通过生成的链接重新填写下方设置" />
<input class="form-control" id="urlshortLinkPasswdInput" type="text" placeholder="短链密码" />
<button class="btn btn-primary" onclick="parseInputURL()" type="button"> <button class="btn btn-primary" onclick="parseInputURL()" type="button">
解析 解析
</button> </button>
@ -142,16 +142,13 @@
<div class="form-group mb-5"> <div class="form-group mb-5">
<label for="apiLink">配置链接:</label> <label for="apiLink">配置链接:</label>
<div class="input-group mb-2"> <div class="input-group mb-2">
<input class="form-control" id="apiLink" type="text" /> <input class="form-control" id="apiLink" type="text" placeholder="链接" />
<button class="btn btn-primary" onclick="generateURL()" type="button">
生成链接
</button>
<button class="btn btn-primary" onclick="copyToClipboard('apiLink',this)" type="button"> <button class="btn btn-primary" onclick="copyToClipboard('apiLink',this)" type="button">
复制链接 复制链接
</button> </button>
</div> </div>
<div class="input-group"> <div class="input-group">
<input class="form-control" id="apiShortLink" type="text" /> <input class="form-control" id="apiShortLink" type="text" placeholder="链接" />
<input class="form-control" id="password" type="text" placeholder="密码" /> <input class="form-control" id="password" type="text" placeholder="密码" />
<button class="btn btn-primary" onclick="generateShortLink()" type="button"> <button class="btn btn-primary" onclick="generateShortLink()" type="button">
生成短链 生成短链
@ -164,6 +161,7 @@
</button> </button>
</div> </div>
</div> </div>
<!-- footer--> <!-- footer-->
<footer> <footer>
<p class="text-center"> <p class="text-center">
@ -174,5 +172,5 @@
</footer> </footer>
</div> </div>
</body> </body>
<script src="./static/index.js"></script>
</html> </html>

View File

@ -63,7 +63,7 @@ function generateURI() {
noProxy = true; noProxy = true;
} }
if (noSub && noProxy) { if (noSub && noProxy) {
alert("订阅链接和节点分享链接不能同时为空!"); // alert("订阅链接和节点分享链接不能同时为空!");
return ""; return "";
} }
// 获取复选框的值 // 获取复选框的值
@ -103,7 +103,7 @@ function generateURI() {
prepend.trim() === "" || prepend.trim() === "" ||
name.trim() === "" name.trim() === ""
) { ) {
alert("Rule Provider 中存在空值,请检查后重试!"); // alert("Rule Provider 中存在空值,请检查后重试!");
return ""; return "";
} }
providers.push(`[${behavior},${url},${group},${prepend},${name}]`); providers.push(`[${behavior},${url},${group},${prepend},${name}]`);
@ -118,7 +118,7 @@ function generateURI() {
let group = rules[i * 3 + 2].value; let group = rules[i * 3 + 2].value;
// 是否存在空值 // 是否存在空值
if (rule.trim() === "" || prepend.trim() === "" || group.trim() === "") { if (rule.trim() === "" || prepend.trim() === "" || group.trim() === "") {
alert("Rule 中存在空值,请检查后重试!"); // alert("Rule 中存在空值,请检查后重试!");
return ""; return "";
} }
ruleList.push(`[${rule},${prepend},${group}]`); ruleList.push(`[${rule},${prepend},${group}]`);
@ -143,7 +143,7 @@ function generateURI() {
let replaceStr = `<${replaces[i * 2].value}>`; let replaceStr = `<${replaces[i * 2].value}>`;
let replaceTo = `<${replaces[i * 2 + 1].value}>`; let replaceTo = `<${replaces[i * 2 + 1].value}>`;
if (replaceStr.trim() === "") { if (replaceStr.trim() === "") {
alert("重命名设置中存在空值,请检查后重试!"); // alert("重命名设置中存在空值,请检查后重试!");
return ""; return "";
} }
replaceList.push(`[${replaceStr},${replaceTo}]`); replaceList.push(`[${replaceStr},${replaceTo}]`);
@ -154,9 +154,12 @@ function generateURI() {
} }
// 将输入框中的 URL 解析为参数 // 将输入框中的 URL 解析为参数
function parseInputURL() { async function parseInputURL() {
// 获取输入框中的 URL // 获取输入框中的 URL
const inputURL = document.getElementById("urlInput").value; const inputURL = document.getElementById("urlInput").value;
const urlshortLinkPasswdInput = document.getElementById(
"urlshortLinkPasswdInput"
).value;
if (!inputURL) { if (!inputURL) {
alert("请输入有效的链接!"); alert("请输入有效的链接!");
@ -170,13 +173,23 @@ function parseInputURL() {
alert("无效的链接!"); alert("无效的链接!");
return; return;
} }
if (url.pathname.includes("/s/")) {
let hash = url.pathname.substring(url.pathname.lastIndexOf("/s/") + 3);
let q = new URLSearchParams();
q.append("hash", hash);
q.append("password", urlshortLinkPasswdInput);
try {
const response = await axios.get("./short?" + q.toString());
url = new URL(window.location.href + response.data);
} catch (error) {
console.log(error);
alert("获取短链失败,请检查密码!");
}
}
let params = new URLSearchParams(url.search);
// 清除现有的输入框值 // 清除现有的输入框值
clearExistingValues(); clearExistingValues();
// 获取查询参数
const params = new URLSearchParams(url.search);
// 分配值到对应的输入框 // 分配值到对应的输入框
const pathSections = url.pathname.split("/"); const pathSections = url.pathname.split("/");
const lastSection = pathSections[pathSections.length - 1]; const lastSection = pathSections[pathSections.length - 1];
@ -360,19 +373,43 @@ function createRule() {
return div; return div;
} }
function listenInput() {
let selectElements = document.querySelectorAll("select");
let inputElements = document.querySelectorAll("input");
let textAreaElements = document.querySelectorAll("textarea");
inputElements.forEach(function (element) {
element.addEventListener("input", function () {
generateURL();
});
});
textAreaElements.forEach(function (element) {
element.addEventListener("input", function () {
generateURL();
});
});
selectElements.forEach(function (element) {
element.addEventListener("change", function () {
generateURL();
});
});
}
function addRuleProvider() { function addRuleProvider() {
const div = createRuleProvider(); const div = createRuleProvider();
document.getElementById("ruleProviderGroup").appendChild(div); document.getElementById("ruleProviderGroup").appendChild(div);
listenInput();
} }
function addRule() { function addRule() {
const div = createRule(); const div = createRule();
document.getElementById("ruleGroup").appendChild(div); document.getElementById("ruleGroup").appendChild(div);
listenInput();
} }
function addReplace() { function addReplace() {
const div = createReplace(); const div = createReplace();
document.getElementById("replaceGroup").appendChild(div); document.getElementById("replaceGroup").appendChild(div);
listenInput();
} }
function removeElement(button) { function removeElement(button) {
@ -423,7 +460,7 @@ function updateShortLink() {
let hash = apiShortLink.value; let hash = apiShortLink.value;
if (hash.startsWith("http")) { if (hash.startsWith("http")) {
let u = new URL(hash); let u = new URL(hash);
hash = u.pathname.replace("/s/", ""); hash = u.pathname.substring(u.pathname.lastIndexOf("/s/") + 3);
} }
if (password.value.trim() === "") { if (password.value.trim() === "") {
alert("请输入密码!"); alert("请输入密码!");
@ -455,3 +492,5 @@ function updateShortLink() {
alert(error.response.data); alert(error.response.data);
}); });
} }
listenInput();