Nodejs+mySql实现长地址转短地址

一、开发原因

  之前公司用一些在线的转短地址网站,但出来的的地址输入没规则,输入太麻烦了,而且扫码还需要安装一个扫码的软件,在一个就是不能转换本地代理的地址(例:http://192.168.1.200:8080),心累。正好公司有个闲置的电脑做服务器,想着干嘛不搞个本地的转短地址工具,这样可以随意设置,想咋弄就咋弄。

  注:这个插件没有部署到服务器上,只是在本地搭建了一个可运行环境,在局域网内可以随意访问。不过只要部署到服务器,再给个域名,就完全可以用,童鞋们可以自行补全。

二、开发环境

  1. 系统环境:macOS, Version 10.13.1
  2. nodejs (v9.2.0)  后台语言
  3. mysql (v5.7.17)  数据库
  4. MySQLWorkbench (v6.3.10)  数据库可视化工具
  5. Chrome Extension  Chrome插件

三、分析开发流程

  1. 获取长链接地址
  2. 把地址传给后台
  3. 查找数据库里面是否存在改地址
  4. 生成短地址
  5. 返回短地址数据

四、开发流程

 4.1 分析数据库、搭建数据库

   数据库至少需要三个字段(id、长地址、短地址),三个字段一目了然就不做介绍了。装好mySql后大神可以直接用命令行建数据库,我这里用的一个可视化工具(MySQLWorkbench)建的数据库。对于数据库最重要的一点是要设置字符集格式,因为地址中会出现一些类似xxx=xxx&xxx=xxx这样的数据,这样在做比较的时候就会报错。可以添加如下代码解决: 

1 SET collation_connection = ‘utf8_general_ci‘;
2 ALTER DATABASE url CHARACTER SET utf8 COLLATE utf8_general_ci;
3 ALTER TABLE url.shortUrl CONVERT TO CHARACTER SET utf8 COLLATE utf8_general_ci;

 4.2 搭建后台程序框架

    后台框架很简单,主要两个文件就搞定,结构如下:

    app.js文件用来开本地服务,以及处理传进来的信息(长地址)。mysqlPool.js用来操作数据库。

app.js:

 1 var http = require(‘http‘);
 2 var url = require(‘url‘);
 3 var UrlInfo = require(‘./routes/mysqlPool‘);
 4
 5 var serve = http.createServer(function(req, res){
 6    // 过滤favicon.ico请求
 7     if(req.url !== ‘/favicon.ico‘){
 8         var obj = url.parse(req.url, true);
 9         var pathname = obj.pathname;
10         // 分割地址信息
11         var nameArr = pathname.toString().split(‘/‘);
12
13         if(nameArr[1] === ‘‘){
14             res.end();
15         }else if(nameArr[1] === ‘insert‘){  // 表示插入操作
16             var firstChart = obj.search.indexOf(‘=‘);
17             //获取需要存储的长地址
18             var longAddress = obj.search.substring(firstChart+1, obj.search.length);
19             // 根据长地址查询数据库是否存在此条信息。
20             UrlInfo.getUrlInfoByLongAddress(longAddress, function(err, reuslt){
21                 if(err){
22                     // 这里对数据库的字符集设置有要求,如果设置不对则会报错,具体设置参考上面数据库搭建
23                     console.log(err);
24                 }else{
25                     // 如果存在这条信息,则返回短地址
26                     if(reuslt.length > 0){
27                         var longUrl = reuslt[0].longAddress;
28                         var shortUrl = reuslt[0].shortAddress;
29                         var data = {
30                             ‘longAddress‘: longUrl,
31                             ‘shortAddress‘: shortUrl
32                         };
33                         res.write(JSON.stringify(data));
34                         res.end();
35                     }else{
36                         // 查询最大的id值
37                         UrlInfo.getMaxId(function(err, reuslt){
38                             var maxID = reuslt[0][‘max(id)‘];
39                             // 如果id号大于或等于99则清空数据库,保证短地址最短,这个值看需求设置
40                             if(maxID >= 99){
41                                 UrlInfo.deleteAllData(function(err, reuslt){
42                                     if(reuslt){
43                                         maxID = 0;
44                                         UrlInfo.insertInfo(maxID + 1, longAddress, function(err, reuslt, backData){
45                                             if(reuslt){
46                                                 var data = {
47                                                     ‘longAddress‘: backData.longAddress,
48                                                     ‘shortAddress‘: backData.shortAddress
49                                                 };
50                                                 res.write(JSON.stringify(data));
51                                             }
52                                             res.end();
53                                         });
54                                     }else{
55                                         res.end();
56                                     }
57                                 });
58                             }else{
59                                 // 插入新信息并返回短地址
60                                 UrlInfo.insertInfo(maxID + 1, longAddress, function(err, reuslt, backData){
61                                     if(reuslt){
62                                         var data = {
63                                             ‘longAddress‘: backData.longAddress,
64                                             ‘shortAddress‘: backData.shortAddress
65                                         };
66                                         res.write(JSON.stringify(data));
67                                         res.end();
68                                     }else{
69                                         res.end();
70                                     }
71                                 });
72                             }
73                         });
74                     }
75                 }
76             });
77         }else{  // 表示请求操作
78             UrlInfo.getUrlInfoById(nameArr[1], function(err, reuslt){
79                 // 如果请求格式错误则跳到百度去(免费打了个广告)
80                 if(err){
81                     res.writeHead(302, {
82                         ‘Location‘: ‘http://www.baidu.com‘
83                     });
84                 }else{
85                     // 根据id获取到对应的短地址
86                     var longUrl = reuslt[0].longAddress;
87                     // 重定向操作,实现短地址跳转到长地址
88                     res.writeHead(302, {
89                         ‘Location‘: longUrl
90                     });
91                 }
92                 res.end();
93             });
94         }
95     }
96 }).listen(3000);

mysqlPool.js:

  1 var mysql = require(‘mysql‘);
  2
  3 var ipConfig = ‘http://192.168.1.200:3000/‘;
  4
  5 //创建一个连接池
  6 var pool = mysql.createPool({
  7     host: ‘127.0.0.1‘,
  8     user: ‘root‘,
  9     password: ‘1234‘,
 10     database: ‘url‘,
 11     port: ‘3306‘
 12 });
 13
 14 pool.on(‘connection‘, function(connection) {
 15     connection.query(‘SET SESSION auto_increment_increment=1‘);
 16 });
 17
 18
 19 module.exports = {
 20     // 这里对错误用try,catch抓取,防止错误导致服务器关闭,当然这些错误都没处理,要想完整一些可以自行处理
 21     // 这里每个方法都有一个数据库链接操作,可以提炼公共的方法来简化代码
 22     getUrlInfoById: function(id, callback){
 23         pool.getConnection(function(err, connection){
 24             connection.query("USE url", function(err){
 25                 if (err) {
 26                     console.log("USE Error: " + err.message);
 27                     return;
 28                  }
 29                  console.log(‘USE succeed‘);
 30             });
 31
 32             connection.query("select * from shorturl where id=?", [id], function(err, result){
 33                 try{
 34                     connection.release();
 35                     callback(err, result);
 36                 }catch(errInfo){
 37                     console.log("select User_Sql Error: " + errInfo.message);
 38                     callback(errInfo, result);
 39                 }
 40             });
 41         });
 42     },
 43     getUrlInfoByLongAddress: function(longAddress, callback){
 44         pool.getConnection(function(err, connection){
 45             connection.query("USE url", function(err){
 46                 if (err) {
 47                     console.log("USE Error: " + err.message);
 48                     return;
 49                  }
 50                  console.log(‘USE succeed‘);
 51             });
 52
 53             connection.query("select * from shorturl where longAddress=?", [longAddress], function(err, result){
 54                 try{
 55                     connection.release();
 56                     callback(err, result);
 57                 }catch(errInfo){
 58                     console.log("select User_Sql Error: " + errInfo.message);
 59                     callback(errInfo, result);
 60                 }
 61             });
 62         });
 63     },
 64     getMaxId: function(callback){
 65         pool.getConnection(function(err, connection){
 66             connection.query("USE url", function(err){
 67                 if (err) {
 68                     console.log("USE Error: " + err.message);
 69                     return;
 70                  }
 71                  console.log(‘USE succeed‘);
 72             });
 73
 74             connection.query("select max(id) from shorturl", function(err, result){
 75                 try{
 76                     connection.release();
 77                     callback(err, result);
 78                 }catch(errInfo){
 79                     console.log("select User_Sql Error: " + errInfo.message);
 80                     callback(errInfo, result);
 81                 }
 82             });
 83         });
 84     },
 85     insertInfo: function(id, longAddress, callback){
 86         pool.getConnection(function(err, connection){
 87             connection.query("USE url", function(err){
 88                 if (err) {
 89                     console.log("USE Error: " + err.message);
 90                     return;
 91                  }
 92                  console.log(‘USE succeed‘);
 93             });
 94
 95             connection.query("insert into shorturl(id,longAddress,shortAddress) values(?,?,?)", [id, longAddress, ipConfig + id], function(err, result){
 96                 try{
 97                     connection.release();
 98                     callback(err, result, {
 99                         ‘longAddress‘: longAddress,
100                         ‘shortAddress‘: ipConfig + id
101                     });
102                 }catch(errInfo){
103                     console.log("select User_Sql Error: " + errInfo.message);
104                     callback(errInfo, result, {
105                         ‘longAddress‘: longAddress,
106                         ‘shortAddress‘: ipConfig + id
107                     });
108                 }
109             });
110         });
111     },
112     deleteAllData: function(callback){
113         pool.getConnection(function(err, connection){
114             connection.query("USE url", function(err){
115                 if (err) {
116                     console.log("USE Error: " + err.message);
117                     return;
118                  }
119                  console.log(‘USE succeed‘);
120             });
121
122             connection.query("delete from shorturl where 1=1", function(err, result){
123                 try{
124                     connection.release();
125                     callback(err, result);
126                 }catch(errInfo){
127                     console.log("select User_Sql Error: " + errInfo.message);
128                     callback(errInfo, result);
129                 }
130             });
131         });
132     },
133 };

    这里数据库操作很简洁,因为使用人数比较少,所以就没有做什么数据库回滚、死锁等操作,如果面向人群比较多,这些并发性还是要考虑的。这里就随意啦~~~

    到这里整个工具基本上完成了,但是要获取到需要转换的长地址总不能Ctrl+C、Ctrl+V吧。这样非人性化的工具,咱码农可拿不出手的。所以用Chrome插件工具就可以完美完成这个任务。

 4.3 Chrome插件开发

    这里插件的具体配置、开发我就不啰嗦了,官方文档分分钟搞定。我就贴一下配置文件和主要实现代码吧。

目录结构:

manifest.json:(Chrome插件配置文件)

 1 {
 2     "name": "Link",
 3     "version": "0.1",
 4     "manifest_version": 2,
 5     "description": "long to short",
 6     "icons": {
 7         "100": "image/icon.png"
 8     },
 9     "browser_action": {
10         "default_icon": "image/icon.png",
11         "default_popup": "popup.html"
12     },
13     "background": {
14         "scripts": ["bjs/jquery-2.0.3.min.js", "bjs/background.js"]
15     },
16     "permissions": [
17         "tabs"
18     ],
19     "content_scripts": [{
20         "matches": ["<all_urls>"],
21         "js": ["bjs/jquery-2.0.3.min.js"],
22         "all_frames": true,
23         "match_about_blank": true,
24         "run_at": "document_start"
25     }]
26 }

popup.js:

 1 $(function () {
 2     getCurrentTab(function(tabs){
 3         if(tabs){
 4             // 设置服务器的ip地址
 5             var joinIP = ‘http://192.168.1.200:3000/insert?longAddress=‘;
 6             // ajax访问服务器
 7             $.getJSON(joinIP + tabs.url, function (data) {
 8                 $(‘.long-url‘).html(tabs.url);
 9                 $(‘.short-url‘).html(data.shortAddress);
10                 $(‘.loading-box‘).hide();
11                 console.log(data);
12             });
13         }else{
14             console.log(‘no tab‘);
15         }
16     });
17     // 获取到当前网站信息
18     function getCurrentTab(callback) {
19         chrome.tabs.query({
20             active: true,
21             currentWindow: true
22         }, function (tabs) {
23             if (callback) callback(tabs.length ? tabs[0] : null);
24         });
25     }
26 })

五、启动方式

  1. 添加Chrome插件到Chrome浏览器
  2. 在命令行定位到项目工程文件
  3. 运行node app命令开启本地服务
  4. 找一个地址,点击那个插件生成短地址测试
  5. 完成

六、结果截图

    亲测有效~~~

七、迁移到Windows服务器

  1. 系统环境:win7系统(32位)------ 一脸懵逼的吐槽公司这台闲置的电脑,这配置~~~
  2. nodejs (v8.11.2)  后台语言 ------ 直接下载msi文件点击安装
  3. mysql (v8.....忘记了)  数据库 ------ 下载msi文件跟着步骤安装
  4. MySQLWorkbench (v6.3.10)  数据库可视化工具
  5. 再次吐槽一下这台电脑,.Net Framework版本低的不要不要的,mySql软件需要的环境都要升级,折腾一下午终于搞定,至于配置方式可以百度解决
  6. Windows有个好处就是可以设置开机运行脚本,这样每次启动就可以自动开启服务了,不需要每次手动去开。
  7. 新建一个txt文件,里面输入node C:\url\app(因为我把工程文件就放在了c盘下面),如果路径不同可以自行调整
  8. 保存txt文件,然后把文件后缀改成bat,然后添加到开机启动项里面,这里推荐一篇关于设置启动项的文章:http://blog.51cto.com/10676568/1974842
  9. 重启电脑测试~~~

原文地址:https://www.cnblogs.com/lawliet-qiu/p/9123185.html

时间: 2024-08-28 13:05:05

Nodejs+mySql实现长地址转短地址的相关文章

长网址转换短网址

可以用955网址转换网站 以下是原理:http://blog.sina.com.cn/s/blog_65db99840100lg4n.html(转) ----------------“今天看到新闻说谷歌的网址缩短服务(http://goo.gl/)向公众开放了,就想看看这短地址是怎么一回事,因为玩新浪微博的时候也经常碰到这个东西. 用我的博客地址http://blog.sina.com.cn/bluemonster0808生成的短地址是goo.gl/HdAU(值得注意的是同一个长地址每次生成的短

C#如何实现url短地址?C#短网址压缩算法与短网址原理入门

c# url短地址压缩算法与短网址原理的例子,详细介绍了短网址的映射算法,将长网址md5生成32位签名串,分为4段,每段8个字节,然后生成短网址,具体见文本实例. 短网址映射算法: 将长网址md5生成32位签名串,分为4段,每段8个字节:对这四段循环处理,取8个字节,将他看成16进制串与0x3fffffff(30位1)与操作,即超过30位的忽略处理:这30位分成6段,每5位的数字作为字母表的索引取得特定字符,依次进行获得6位字符串:总的md5串可以获得4个6位串:取里面的任意一个就可作为这个长u

URL短地址压缩算法

时下,短网址应用已经在全国各大微博上开始流行了起来.例如QQ微博的url.cn,新郎的t.cn等.我们在新浪微博上发布网址的时候,微博会自动判别网址,并将其转换,例如:http://t.cn/hrYnr0.为什么要这样做的,原因我想有这样几点: 1.微博限制字数为140字一条,那么如果我们需要发一些连接上去,但是这个连接非常的长,以至于将近要占用我们内容的一半篇幅,这肯定是不能被允许的,所以短网址应运而生了. 2.短网址可以在我们项目里可以很好的对开放级URL进行管理.有一部分网址可以会涵盖性.

URL压缩算法的短地址

时下,短网址应用已经在全国各大微博上開始流行了起来.比如QQ微博的url.cn,新郎的t.cn等. 我们在新浪微博上公布网址的时候.微博会自己主动判别网址.并将其转换,比如:http://t.cn/hrYnr0. 为什么要这样做的.原因我想有这样几点: 1.微博限制字数为140字一条,那么假设我们须要发一些连接上去,可是这个连接很的长,以至于将近要占用我们内容的一半篇幅,这肯定是不能被同意的,所以短网址应运而生了. 2.短网址能够在我们项目里能够非常好的对开放级URL进行管理.有一部分网址能够会

短地址TinyURL的API使用

TinyURL的短地址服务超过10年了,很稳定,官方没有给出API连接,其实很简单: API: 调用:http://tinyurl.com/api-create.php?url=http://URL,  你可以发送一个request到这个地址, Response中只有一个字符串,就是你的短地址URL; php例子: /** * 获取短地址 * [@param](/user/param) $url 需要处理的长地址 * [@return](/user/return) string */ priva

URL短地址压缩算法 微博短地址原理解析 (Java实现)

最近,项目中需要用到短网址(ShortUrl)的算法,于是在网上搜索一番,发现有C#的算法,有.Net的算法,有PHP的算法,就是没有找到Java版的短网址(ShortUrl)的算法,很是郁闷.同时还发现有不少网友在发帖求助,怎么实现Java版的短网址(ShortUrl)的算法.干脆一不做,二不休,参考了一下网上比较流行的PHP版短网址(ShortUrl)算法: 再根据自己的理解,用Java实现了该短网址(ShortUrl)的算法.(\(^o^)/YES!我还真厉害!) 先来废话一下,是在别人的

使用EJS生成短地址

此博客为9925.org的镜像,登录9925.org可以查看到最新博文. 原文出处:http://ily.so/MnUFBf 使用EJS脚本可以轻松调用webapi接口,下面的例子是调用ily.so短地址服务的,请参考. clear(); var url = prompt("请输入要缩短的地址:"); if(url != null && url != "") {     var re = /((http|https):\/\/)(([a-zA-Z0-

转载 URL短地址压缩算法

由于文章转载太多,所以找到出处,作者看到别生气 - - /// <summary> /// 生成salt /// </summary> /// <returns></returns> public static string GenerateSalt() { byte[] data = new byte[0x10]; new RNGCryptoServiceProvider().GetBytes(data); return Convert.ToBase64S

mysql长连接与短连接

什么是长连接? 其实长连接是相对于通常的短连接而说的,也就是长时间保持客户端与服务端的连接状态. 通常的短连接操作步骤是: 连接->数据传输->关闭连接: 而长连接通常就是: 连接->数据传输->保持连接->数据传输->保持连接->…………->关闭连接: 这就要求长连接在没有数据通信时,定时发送数据包,以维持连接状态,短连接在没有数据传输时直接关闭就行了 什么时候用长连接,短连接? 长连接主要用于在少数客户端与服务端的频繁通信,因为这时候如果用短连接频繁通信