Nginx手动实现短链接 - wuuconix's blog

背景

有时候想要给同学分享一个链接,但是这个链接可能很长,就显得很难看。

以前我的解决办法是新建一个子域名,然后再Nginx配置文件里 rewrite 到那个链接。效果如下。

代码语言:javascript
复制
graph LR
1(("用户"))
2[("跳转到武丑兄的github页面<br>https://github.com/wuuconix")]
3[("跳转到武丑兄的dockerhub页面<br>https://hub.docker.com/u/wuuconix")]
1--"通过git.wuucoinx.link"-->2
1--"通过docker.wuucoinx.link"-->3

实现主要利用的Nginx配置文件中的rewrite重写url。以下是 git.wuuconix.link 的配置文件。

代码语言:javascript
复制
server
{
   listen 443 ssl;# https 监听的是 443端口
   server_name  git.wuuconix.link;

keepalive_timeout 100;

ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;

ssl_certificate /etc/nginx/ssl-link/fullchain.crt; # 证书路径
ssl_certificate_key /etc/nginx/ssl-link/private.pem; # 请求认证 key 的路径

ssl_protocols TLSv1.1 TLSv1.2;
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:HIGH:!aNULL:!MD5:!RC4:!DHE;
ssl_prefer_server_ciphers on;
ssl_session_cache shared:SSL:10m;

rewrite ^(.*) https://github.com/wuuconix permanent;
}

server
{
listen 80;
server_name git.wuuconix.link;
rewrite ^(.*) https://$server_name$1 permanent;
}

但是随着需要需求的增加,二级域名已经变得难以满足了。

实际上之前我子托管过 YOURLS ,Vaala还向我推荐过 kutt,但是我鉴于容器开起来需要占用资源,像YOURLS开需要开配套的数据库,很麻烦。

所以我便想用功能强大的Nginx手动实现一个满足实际需求的短链生成器。

实现过程

首先我预期实现的目标类似下图。

代码语言:javascript
复制
graph LR
1(("用户"))
2[("跳转到fomantic-UI文档<br>https://fomantic-ui.com/")]
3[("跳转到mermaid在线编辑器<br>https://mermaid-js.github.io/mermaid-live-editor")]
1--"通过url.wuuconix.link/fomantic"-->2
1--"通过url.wuuconix.link/mermaid"-->3

这和之前用子域名来区分跳转的服务不同,现在是用着同一个子域名,即 url.wuuconix.link

只不过是通过域名后面的路径来确定不同的跳转对象的。

经过搜索,发现Nginx中的 Location就能很好的实现功能。例子如下。

代码语言:javascript
复制
server
{
listen 443 ssl;# https 监听的是 443端口
server_name url.wuuconix.link;

keepalive_timeout 100;

ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;

ssl_certificate /etc/nginx/ssl-link/fullchain.crt; # 证书路径
ssl_certificate_key /etc/nginx/ssl-link/private.pem; # 请求认证 key 的路径

ssl_protocols TLSv1.1 TLSv1.2;
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:HIGH:!aNULL:!MD5:!RC4:!DHE;
ssl_prefer_server_ciphers on;
ssl_session_cache shared:SSL:10m;

location / {
root /var/www/url;
index index.html;
}

location = /mermaid {
rewrite ^(.*) https://mermaid-js.github.io/mermaid-live-editor/ permanent;
}

location = /fomantic-ui {
rewrite ^(.*) https://fomantic-ui.com/ permanent;
}
}

server
{
listen 80;
server_name url.wuuconix.link;
rewrite ^(.*) https://$server_name$1 permanent;
}

存在的问题

  1. 这样手动写貌似有点慢,最好能有一个程序接收我的长链接 和 我需要的短链接,然后自动帮我把配置文件写好。
  2. 缺少一个导航页,我很可能自己都忘记短链接有哪些,到时候分享给同学就很狼狈。

改进

我写了一个python脚本,在终端接收我的长短链接,然后自动帮我设置。

此外我还写了个简单的导航。https://url.wuuconix.link

当然了,python脚本也会去实时跟新导航页的内容。

代码语言:javascript
复制
import sys
import random

def readFromFile(filename:str)->str:
with open(filename, "r") as f: #读文件
string = f.read()
return string

def writeToFile(filename:str, content:str):
with open(filename, "w") as f: #读文件
f.write(content)

short = sys.argv[1]
url = sys.argv[2]
description = sys.argv[3]

rand = 1 if random.randint(0, 65535) % 2 == 0 else 2 #随机添加到 左边还是右边

patternForConf = "\n location = /" + short + " {\n rewrite ^(.*) " + url + " permanent;\n }\n #continue"
patternForHtml = '<div class="item">\n'
+ " " * 20 + '<i class="map marker icon"></i>\n'
+ " " * 20 + '<div class="content">\n'
+ " " * 24 + f'<a class="header" href="https://url.wuuconix.link/{short}" target="_blank">' + f"https://url.wuuconix.link/{short}" + '</a>\n'
+ " " * 24 + '<div class="description">' + description + '</div>\n'
+ " " * 20 + '</div>\n'
+ " " * 16 + '</div>\n'
+ " " * 16 + f'<!-- continue{rand} -->'

filenameConf = "/etc/nginx/sites-enabled/url.wuuconix.link.conf"
filenameGuide = "/var/www/url/index.html"

conf = readFromFile(filenameConf)
conf = conf.replace("#continue", patternForConf)
writeToFile(filenameConf, conf)

htmls = readFromFile(filenameGuide)
htmls = htmls.replace(f"<!-- continue{rand} -->", patternForHtml)
writeToFile(filenameGuide, htmls)

结果

导航页:https://url.wuuconix.link

希望能够帮到你!

导航页预览