├── README.md ├── certificate ├── xxxxx.key └── xxxxx.pem ├── config └── keys.js ├── core └── function.js ├── index.js ├── models └── Statistic.js ├── package-lock.json ├── package.json ├── public ├── bing.html ├── cloudmusic.html ├── css │ └── main.css ├── favicon.ico ├── icp.html ├── imgs │ ├── logo.png │ └── map.jpg ├── index.html ├── js │ ├── index.js │ └── jquery.countup.min.js ├── longurl.html ├── onenote.html ├── qqinfo.html ├── qrcode.html ├── qrdecode.html ├── sitetitle.html ├── static │ └── particles.json └── tinyurl.html ├── routes └── api │ ├── bing.js │ ├── cloudmusic.js │ ├── icp.js │ ├── longurl.js │ ├── onenote.js │ ├── qqinfo.js │ ├── qrcode.js │ ├── qrdecode.js │ ├── sitetitle.js │ ├── statistic.js │ └── tinyurl.js └── static └── files └── onenote.txt /README.md: -------------------------------------------------------------------------------- 1 | ## 说明 一个基于Express框架的api接口,包括短网址生成、短网址还原、二维码生成、二维码识别解析、网站标题获取、ICP备案查询、网易云音乐解析、QQ信息获取、一言、必应每日一图。 数据库为MongoDB。 ## 演示网站:[https://api.no0a.cn/](https://api.no0a.cn/ "https://api.no0a.cn/") ## 首页截图: ![首页截图](https://imgs.bwmelon.com/20190808213126.png) ## 使用 ``` #安装依赖 $ npm install #启动项目,默认端口为3000 $ npm start ``` ## TODO - [x] 前台文档页面 - [x] 接口使用次数统计 - [x] 接口调用频率限制 - [ ] ip黑名单 - [ ] 后台自定义接口的开启与关闭 - [ ] 加入更多接口 ## 接口文档 ### 短网址生成 接口: `http://127.0.0.1:3000/api/tinyurl/urlcn/?longurl=` `http://127.0.0.1:3000/api/tinyurl/tcn/?longurl=` 示例: `http://127.0.0.1:3000/api/tinyurl/urlcn/?longurl=http://api.no0a.cn` 返回: ``` { "status": 1, "tinyurl": "https://url.cn/5fpMHji" } ``` ### 短网址还原 接口: `http://127.0.0.1:3000/api/longurl/query?tinyurl=` 示例: `http://127.0.0.1:3000/api/longurl/query?tinyurl=https://t.cn/AiYNrqef` 返回: ``` { "status": 1, "longurl": "http://api.no0a.cn/" } ``` ### 二维码生成 接口: `http://127.0.0.1:3000/api/qrcode/query?url=` 示例: `http://127.0.0.1:3000/api/qrcode/query?url=http://api.no0a.cn` 返回: ``` 直接返回png格式的二维码 ``` ### 二维码识别解析 接口: `http://127.0.0.1:3000/api/qrdecode/query?imgurl=` 示例: `http://127.0.0.1:3000/api/qrdecode/query?imgurl=https://imgs.bwmelon.com/20190803222039.png` 返回: ``` { "status": 1, "qrurl": "https://i.qianbao.qq.com/wallet/sqrcode.htm?m=tenpay&f=wallet&a=1&ac=CAEQl4jHtQUYz93y6AU%3D_xxx_sign&u=1454490647&n=%E6%89%93%EF%BC%8C%E6%89%93%E4%B8%AA%E5%A4%A7%E8%A5%BF%E7%93%9C%E3%80%80" } ``` ### 网站标题获取 接口: `http://127.0.0.1:3000/api/sitetitle/query?url=` 示例: `http://127.0.0.1:3000/api/sitetitle/query?url=https://qr.no0a.cn` 返回: ``` { "status": 1, "title": "大西瓜三合一收款码" } ``` ### ICP备案查询 接口: `http://127.0.0.1:3000/api/icp/query?domain=` 示例: `http://127.0.0.1:3000/api/icp/query?domain=qq.com` 返回: ``` { "status": 1, "info": { "name": "深圳市腾讯计算机系统有限公司", "properties": "企业", "icp": "粤B2-20090059-5", "title": "腾讯网", "people": "--", "time": "2019/8/1 0:00:00" } } ``` ### 网易云音乐解析 接口: `搜索:https://api.no0a.cn/api/cloudmusic/search/key` `解析:https://api.no0a.cn/api/cloudmusic/url/id` `信息:https://api.no0a.cn/api/cloudmusic/info/id` `歌词:https://api.no0a.cn/api/cloudmusic/lyric/id` `歌单:https://api.no0a.cn/api/cloudmusic/playlist/id` 示例: `搜索:https://api.no0a.cn/api/cloudmusic/search/偏爱` `解析:https://api.no0a.cn/api/cloudmusic/url/86369` `信息:https://api.no0a.cn/api/cloudmusic/info/86369` `歌词:https://api.no0a.cn/api/cloudmusic/lyric/86369` `歌单:https://api.no0a.cn/api/cloudmusic/playlist/2796626278` 返回: ``` { "status": 1, "results": [ { "name": "偏爱", "id": 86369, "artist": [ { "name": "张芸京" } ] }, { "name": "偏爱", "id": 328076, "artist": [ { "name": "张芸京" } ] }, { "name": "此生不换", "id": 86363, "artist": [ { "name": "青鸟飞鱼" } ] } ] } ``` ``` { "status": 1, "musicurl": "http://m8.music.126.net/20190810162950/cb941dff97550a297f9888cb96251ec0/ymusic/2f43/79c5/bd3c/7fe89e927098b086e99223a996189cba.mp3" } ``` ``` { "status": 1, "musicinfo": { "name": "偏爱", "artist": [ { "name": "张芸京" } ] } } ``` ``` { "status": 1, "musiclyric": "[by:Kyu9n]\n[00:00.000] 作曲 : 陈伟\n[00:01.000] 作词 : 葛大为\n[00:15.50]把昨天都作废\n[00:18.91]现在你在我眼前\n[00:22.69]我想爱 请给我机会\n[00:29.19]如果我错了也承担\n[00:33.07]认定你就是答案\n[00:37.76]我不怕谁嘲笑我极端\n[00:42.07]\n[00:42.92]相信自己的直觉\n[00:46.78]顽固的人不喊累\n[00:50.27]爱上你 我不撤退\n[00:55.19]\n[00:55.70]我说过 我不闪躲\n[00:59.12]我非要这么做\n[01:01.83]讲不听 也偏要爱\n[01:04.27]更努力爱 让你明白\n[01:09.37]没有别条路能走\n[01:12.58]你决定要不要陪我\n[01:15.50]讲不听 偏爱\n[01:17.22]靠我感觉爱\n[01:18.94]等你的依赖\n[01:21.90]对你偏爱\n[01:29.18]痛也很愉快\n[01:36.06]\n[01:37.82]把昨天都作废\n[01:41.20]现在你在我眼前\n[01:44.91]我想爱 请给我机会\n[01:51.49]如果我错了也承担\n[01:55.40]认定你就是答案\n[02:00.14]我不怕谁嘲笑我极端\n[02:04.37]\n[02:05.18]相信自己的直觉\n[02:09.05]顽固的人不喊累\n[02:12.54]爱上你 我不撤退\n[02:17.59]\n[02:18.01]我说过 我不闪躲\n[02:21.44]我非要这么做\n[02:24.09]讲不听 也偏要爱\n[02:26.55]更努力爱 让你明白\n[02:31.79]没有别条路能走\n[02:34.77]你决定要不要陪我\n[02:37.80]讲不听 偏爱\n[02:39.54]靠我感觉爱\n[02:41.20]等你的依赖\n[02:44.04]\n[02:44.22]不后悔 有把握\n[02:47.12]我不闪躲 我非要这么做\n[02:51.46]讲不听 也偏要爱\n[02:53.92]更努力爱 让你明白\n[02:59.16]没有别条路能走\n[03:02.17]你决定要不要陪我\n[03:05.22]讲不听 偏爱\n[03:06.95]靠我感觉爱\n[03:08.74]等你的依赖\n[03:11.64]对你偏爱 爱\n[03:18.91]痛也很愉快\n[03:26.57]\n" } ``` ``` { "status": 1, "results": [ { "name": "カノン", "id": 4894309, "artist": [ { "name": "DJ Okawari" } ] }, { "name": "Adagio for Summer Wind", "id": 760037, "artist": [ { "name": "清水準一" } ] }, { "name": "やわらかな光", "id": 28287132, "artist": [ { "name": "やまだ豊" } ] }, { "name": "一弯明月", "id": 362446, "artist": [ { "name": "陈嘉玲" } ] } ] } ``` ### QQ信息获取 接口: `http://127.0.0.1:3000/api/qqinfo/qq` 示例: `http://127.0.0.1:3000/api/qqinfo/10001` 返回: ``` { "status": 1, "qqinfo": { "nickname": "pony", "qqavatar": "http://q1.qlogo.cn/g?b=qq&s=640&nk=10001" } } ``` ### 一言 接口: `http://127.0.0.1:3000/api/onenote/query` 示例: `http://127.0.0.1:3000/api/onenote/query` 返回: ``` { "status": 1, "onenote": "你说你会爱我一辈子,我真傻,居然忘了问是这辈子还是下辈子。" } ``` ### 必应每日一图 接口: `http://127.0.0.1:3000/api/bing/day` day为时间,0表示当天,1-7表示过去的1-7天,最多为过去7天 示例: `http://127.0.0.1:3000/api/bing/0` `http://127.0.0.1:3000/api/bing/1` `http://127.0.0.1:3000/api/bing/3` `http://127.0.0.1:3000/api/bing/7` 返回: ``` "status": 1, "bing": { "url": "http://s.cn.bing.net/th?id=OHR.UhuRLP_ZH-CN5421658032_1920x1080.jpg&rf=LaDigue_1920x1080.jpg&pid=hp", "copyright": "野花草甸上的一只欧亚雕鸮,德国莱茵兰-普法尔茨 (© Rosl Roessner/Minden Pictures)" } } ``` ## 宝塔安装教程 [https://www.bwmelon.com/archives/27/](https://www.bwmelon.com/archives/27/) -------------------------------------------------------------------------------- /certificate/xxxxx.key: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BWmelon/BWmelonApi/482f7ffdf55d3ef104840a9fc9c500e8a7e7c8bf/certificate/xxxxx.key -------------------------------------------------------------------------------- /certificate/xxxxx.pem: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BWmelon/BWmelonApi/482f7ffdf55d3ef104840a9fc9c500e8a7e7c8bf/certificate/xxxxx.pem -------------------------------------------------------------------------------- /config/keys.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | mongoURI: "mongodb://localhost:27017/BwmelonApi", 3 | secretOrKey: "secret" 4 | } -------------------------------------------------------------------------------- /core/function.js: -------------------------------------------------------------------------------- 1 | const StatisticSchema = require("../models/Statistic"); 2 | const mongoose = require("mongoose"); 3 | 4 | function Core() { 5 | // 使用次数统计 6 | this.statAdd = function (api) { 7 | mongoose.set('useFindAndModify', false); 8 | Statistic.findOne({ 9 | api 10 | }) 11 | .then(exist => { 12 | if (exist) { 13 | let time = ++exist.time; 14 | Statistic.findOneAndUpdate({ 15 | api 16 | }, { 17 | api, 18 | time: time 19 | }) 20 | .then(statistic => { 21 | // console.log(statistic) 22 | }) 23 | .catch(err => { 24 | // console.log(err) 25 | }); 26 | 27 | 28 | } else { 29 | const newStatistic = new StatisticSchema({ 30 | api, 31 | time: 1 32 | }) 33 | newStatistic.save() 34 | .then(statistic => { 35 | // console.log(statistic) 36 | }) 37 | .catch(err => { 38 | // console.log(err) 39 | }); 40 | } 41 | }); 42 | } 43 | 44 | // 使用次数查询 45 | this.statQuery = function () { 46 | return new Promise((res, rej) => { 47 | mongoose.set('useFindAndModify', false); 48 | Statistic.find({}) 49 | .then(exist => { 50 | let arr = {}; 51 | for (const api in exist) { 52 | if (exist.hasOwnProperty(api)) { 53 | const apiName = exist[api].api; 54 | const apiTime = exist[api].time; 55 | arr[apiName] = apiTime; 56 | } 57 | } 58 | res(arr); 59 | }) 60 | .catch(err => rej(err)); 61 | }) 62 | 63 | } 64 | } 65 | 66 | module.exports = Core; -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | const express = require("express"); 2 | const cors = require('cors'); 3 | const app = express(); 4 | const mongoose = require("mongoose"); 5 | const bodyParser = require("body-parser"); 6 | 7 | const path = require('path'); 8 | const fs = require('fs'); 9 | const https = require('https'); 10 | const RateLimit = require('express-rate-limit'); 11 | 12 | 13 | 14 | // 跨域 15 | app.use(cors()); 16 | 17 | // 静态 18 | app.use("/", express.static(path.join(__dirname, 'public'))); 19 | 20 | // 使用body-parser中间件 21 | app.use(bodyParser.urlencoded({extended:false})); 22 | app.use(bodyParser.json()); 23 | 24 | 25 | // 连接数据库 26 | const db = require("./config/keys").mongoURI; 27 | mongoose.connect(db, {useNewUrlParser: true}) 28 | .then(() => { 29 | console.log("Mongodb connected"); 30 | }) 31 | .catch((err) => { 32 | console.log(err); 33 | }) 34 | 35 | // 数据库 36 | const statistic = require("./routes/api/statistic"); 37 | app.use("/api/statistic", statistic); 38 | 39 | // 请求频率限制 40 | var apiLimiter = new RateLimit({ 41 | windowMs: 60 * 60 * 1000, // 1 hour 42 | max: 1000, // 1000 次 43 | delayMs: 0, // disabled 延迟响应 44 | handler: function (req, res) { 45 | res.status(429).json({ 46 | msg: "请求频率过快,当前频率为每小时一千次" 47 | }) 48 | } 49 | }) 50 | app.use(apiLimiter); 51 | 52 | const tinyurl = require("./routes/api/tinyurl"); 53 | const longurl = require("./routes/api/longurl"); 54 | const qrdecode = require("./routes/api/qrdecode"); 55 | const qrcode = require("./routes/api/qrcode"); 56 | const qqinfo = require("./routes/api/qqinfo"); 57 | const sitetitle = require("./routes/api/sitetitle"); 58 | const icp = require("./routes/api/icp.js"); 59 | const onenote = require("./routes/api/onenote"); 60 | const cloudmusic = require("./routes/api/cloudmusic"); 61 | const bing = require("./routes/api/bing"); 62 | 63 | app.use("/api/tinyurl", tinyurl); 64 | app.use("/api/longurl", longurl); 65 | app.use("/api/qrdecode", qrdecode); 66 | app.use("/api/qrcode", qrcode); 67 | app.use("/api/qqinfo", qqinfo); 68 | app.use("/api/sitetitle", sitetitle); 69 | app.use("/api/icp", icp); 70 | app.use("/api/onenote", onenote); 71 | app.use("/api/cloudmusic", cloudmusic); 72 | app.use("/api/bing", bing); 73 | 74 | 75 | 76 | const port = 3000; 77 | app.listen(port, () => { 78 | console.log(`Sever running on port ${port}`); 79 | }); 80 | 81 | 82 | 83 | // https配置 不需要https可将下面代码删除 84 | // const httpsOption = { 85 | // cert: fs.readFileSync("./certificate/xxxxx.pem"), 86 | // key: fs.readFileSync("./certificate/xxxxx.key") 87 | // } 88 | // https.createServer(httpsOption, app).listen(444); -------------------------------------------------------------------------------- /models/Statistic.js: -------------------------------------------------------------------------------- 1 | const mongoose = require("mongoose"); 2 | const Schema = mongoose.Schema; 3 | 4 | const StatisticSchema = new Schema({ 5 | api: { 6 | type:String, 7 | required: true 8 | }, 9 | time: { 10 | type: Number, 11 | default: 1 12 | } 13 | }) 14 | 15 | module.exports = Statistic = mongoose.model("statistics", StatisticSchema); -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "api", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "start": "node index.js", 8 | "server": "nodemon index.js" 9 | }, 10 | "author": "", 11 | "license": "ISC", 12 | "dependencies": { 13 | "bcrypt": "^3.0.6", 14 | "body-parser": "^1.19.0", 15 | "cheerio": "^1.0.0-rc.3", 16 | "concurrently": "^4.1.1", 17 | "cors": "^2.8.5", 18 | "express": "^4.17.1", 19 | "express-rate-limit": "^5.0.0", 20 | "jwt-decode": "^2.2.0", 21 | "mongoose": "^5.6.9", 22 | "passport": "^0.4.0", 23 | "passport-jwt": "^4.0.0", 24 | "qr-decode": "^0.0.3", 25 | "qr-image": "^3.2.0", 26 | "request": "^2.88.0", 27 | "simple-netease-cloud-music": "^0.4.4" 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /public/bing.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 必应每日一图api 15 | 16 | 17 | 18 |
19 | 20 |
21 | 22 |
23 | 52 |
53 | 54 | 55 |
56 |
57 | 58 |
59 |
60 |

接口说明

61 |
62 |
63 | 获取必应当天和前七天的每日一图 64 |
65 |
66 |
67 |
68 |

请求方式

69 |
70 |
71 | GET 72 |
73 |
74 | 75 |
76 |
77 |

请求地址

78 |
79 |
80 |
https://api.no0a.cn/api/bing/day
81 |
82 |
83 | 84 |
85 |
参数说明
86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 |
参数说明
day每日一图时间,0位当前,1为昨天,2为前天,以此类推,最多为前7天
status返回的状态码
bing返回的每日一图信息
url返回的每日一图地址
copyright返回的每日一图版权
msg返回的错误信息
116 |
117 |
118 |
119 |

请求示例

120 |
121 |
122 |
https://api.no0a.cn/api/bing/0
123 |
124 |
125 |
126 |
127 |

返回示例

128 |
129 |
130 |
131 | {
132 |     "status": 1,
133 |     "bing": {
134 |         "url": "http://s.cn.bing.net/th?id=OHR.UhuRLP_ZH-CN5421658032_1920x1080.jpg&rf=LaDigue_1920x1080.jpg&pid=hp",
135 |         "copyright": "野花草甸上的一只欧亚雕鸮,德国莱茵兰-普法尔茨 (© Rosl Roessner/Minden Pictures)"
136 |     }
137 | }
138 |                     
139 | 140 |
141 |
142 | 143 |
144 |
145 | 146 | 147 | 158 | 159 | 160 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | -------------------------------------------------------------------------------- /public/cloudmusic.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 网易云音乐api 15 | 16 | 17 | 18 |
19 | 20 |
21 | 22 |
23 | 52 |
53 | 54 | 55 |
56 |
57 | 58 |
59 |
60 |

接口说明

61 |
62 |
63 | 网易云音乐搜索、歌曲url获取、歌曲信息获取、歌词获取、歌单列表获取 64 |
65 |
66 |
67 |
68 |

请求方式

69 |
70 |
71 | GET 72 |
73 |
74 | 75 |
76 |
77 |

请求地址

78 |
79 |
80 |
搜索:https://api.no0a.cn/api/cloudmusic/search/key
81 |
82 |
83 |
url解析:https://api.no0a.cn/api/cloudmusic/url/id
84 |
85 |
86 |
信息:https://api.no0a.cn/api/cloudmusic/info/id
87 |
88 |
89 |
歌词:https://api.no0a.cn/api/cloudmusic/lyric/id
90 |
91 |
92 |
歌单:https://api.no0a.cn/api/cloudmusic/playlist/id
93 |
94 |
95 | 96 |
97 |
参数说明
98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 |
参数说明
key歌曲搜索关键词
id歌曲id或者歌单id
status状态码
name歌曲名或作者名
id歌曲id
artist作者名列表
musicurl歌曲解析地址,格式为mp3
musiclyric歌词
musicinfo歌曲信息
msg返回的错误信息
144 |
145 | 146 |
147 |
148 |

请求示例:搜索(需先进行url编码)

149 |
150 |
151 |
https://api.no0a.cn/api/cloudmusic/search/偏爱
152 |
153 |
154 |
155 |
156 |

返回示例

157 |
158 |
159 |
160 | {
161 |     "status": 1,
162 |     "results": [
163 |         {
164 |             "name": "偏爱",
165 |             "id": 86369,
166 |             "artist": [
167 |                 {
168 |                     "name": "张芸京"
169 |                 }
170 |             ]
171 |         },
172 |         {
173 |             "name": "偏爱",
174 |             "id": 328076,
175 |             "artist": [
176 |                 {
177 |                     "name": "张芸京"
178 |                 }
179 |             ]
180 |         },
181 |         {
182 |             "name": "此生不换",
183 |             "id": 86363,
184 |             "artist": [
185 |                 {
186 |                     "name": "青鸟飞鱼"
187 |                 }
188 |             ]
189 |         }
190 |     ]
191 | }
192 |                     
193 | 194 |
195 |
196 | 197 |
198 |
199 |

请求示例:url解析

200 |
201 |
202 |
https://api.no0a.cn/api/cloudmusic/url/86369
203 |
204 |
205 |
206 |
207 |

返回示例

208 |
209 |
210 |
211 | {
212 |     "status": 1,
213 |     "musicurl": "http://m8.music.126.net/20190810162950/cb941dff97550a297f9888cb96251ec0/ymusic/2f43/79c5/bd3c/7fe89e927098b086e99223a996189cba.mp3"
214 | }
215 |                     
216 | 217 |
218 |
219 | 220 |
221 |
222 |

请求示例:信息

223 |
224 |
225 |
https://api.no0a.cn/api/cloudmusic/info/86369
226 |
227 |
228 |
229 |
230 |

返回示例

231 |
232 |
233 |
234 | {
235 |     "status": 1,
236 |     "musicinfo": {
237 |         "name": "偏爱",
238 |         "artist": [
239 |             {
240 |                 "name": "张芸京"
241 |             }
242 |         ]
243 |     }
244 | }
245 |                     
246 | 247 |
248 |
249 | 250 |
251 |
252 |

请求示例:歌词

253 |
254 |
255 |
https://api.no0a.cn/api/cloudmusic/lyric/86369
256 |
257 |
258 |
259 |
260 |

返回示例

261 |
262 |
263 |
264 | {
265 |     "status": 1,
266 |     "musiclyric": "[by:Kyu9n]\n[00:00.000] 作曲 : 陈伟\n[00:01.000] 作词 : 葛大为\n[00:15.50]把昨天都作废\n[00:18.91]现在你在我眼前\n[00:22.69]我想爱 请给我机会\n[00:29.19]如果我错了也承担\n[00:33.07]认定你就是答案\n[00:37.76]我不怕谁嘲笑我极端\n[00:42.07]\n[00:42.92]相信自己的直觉\n[00:46.78]顽固的人不喊累\n[00:50.27]爱上你 我不撤退\n[00:55.19]\n[00:55.70]我说过 我不闪躲\n[00:59.12]我非要这么做\n[01:01.83]讲不听 也偏要爱\n[01:04.27]更努力爱 让你明白\n[01:09.37]没有别条路能走\n[01:12.58]你决定要不要陪我\n[01:15.50]讲不听 偏爱\n[01:17.22]靠我感觉爱\n[01:18.94]等你的依赖\n[01:21.90]对你偏爱\n[01:29.18]痛也很愉快\n[01:36.06]\n[01:37.82]把昨天都作废\n[01:41.20]现在你在我眼前\n[01:44.91]我想爱 请给我机会\n[01:51.49]如果我错了也承担\n[01:55.40]认定你就是答案\n[02:00.14]我不怕谁嘲笑我极端\n[02:04.37]\n[02:05.18]相信自己的直觉\n[02:09.05]顽固的人不喊累\n[02:12.54]爱上你 我不撤退\n[02:17.59]\n[02:18.01]我说过 我不闪躲\n[02:21.44]我非要这么做\n[02:24.09]讲不听 也偏要爱\n[02:26.55]更努力爱 让你明白\n[02:31.79]没有别条路能走\n[02:34.77]你决定要不要陪我\n[02:37.80]讲不听 偏爱\n[02:39.54]靠我感觉爱\n[02:41.20]等你的依赖\n[02:44.04]\n[02:44.22]不后悔 有把握\n[02:47.12]我不闪躲 我非要这么做\n[02:51.46]讲不听 也偏要爱\n[02:53.92]更努力爱 让你明白\n[02:59.16]没有别条路能走\n[03:02.17]你决定要不要陪我\n[03:05.22]讲不听 偏爱\n[03:06.95]靠我感觉爱\n[03:08.74]等你的依赖\n[03:11.64]对你偏爱 爱\n[03:18.91]痛也很愉快\n[03:26.57]\n"
267 | }
268 |                     
269 | 270 |
271 |
272 | 273 |
274 |
275 |

请求示例:歌单

276 |
277 |
278 |
https://api.no0a.cn/api/cloudmusic/playlist/2796626278
279 |
280 |
281 |
282 |
283 |

返回示例

284 |
285 |
286 |
287 | {
288 |     "status": 1,
289 |     "results": [
290 |         {
291 |             "name": "カノン",
292 |             "id": 4894309,
293 |             "artist": [
294 |                 {
295 |                     "name": "DJ Okawari"
296 |                 }
297 |             ]
298 |         },
299 |         {
300 |             "name": "Adagio for Summer Wind",
301 |             "id": 760037,
302 |             "artist": [
303 |                 {
304 |                     "name": "清水準一"
305 |                 }
306 |             ]
307 |         },
308 |         {
309 |             "name": "やわらかな光",
310 |             "id": 28287132,
311 |             "artist": [
312 |                 {
313 |                     "name": "やまだ豊"
314 |                 }
315 |             ]
316 |         },
317 |         {
318 |             "name": "一弯明月",
319 |             "id": 362446,
320 |             "artist": [
321 |                 {
322 |                     "name": "陈嘉玲"
323 |                 }
324 |             ]
325 |         }
326 |     ]
327 | }
328 |                     
329 | 330 |
331 |
332 | 333 |
334 |
335 | 336 | 337 | 348 | 349 | 350 | 353 | 354 | 355 | 356 | 357 | 358 | 359 | 360 | 361 | -------------------------------------------------------------------------------- /public/css/main.css: -------------------------------------------------------------------------------- 1 | * { 2 | margin: 0; 3 | padding: 0; 4 | box-sizing: border-box; 5 | } 6 | a, 7 | a:focus, 8 | a:hover { 9 | text-decoration: none; 10 | } 11 | body { 12 | background-image: url(../imgs/map.jpg); 13 | background-size: cover; 14 | background-position-x: center; 15 | } 16 | 17 | /* 导航条 */ 18 | .navbar-inverse { 19 | background-color: transparent; 20 | border-color: transparent; 21 | } 22 | .navbar a, 23 | .navbar-inverse .navbar-brand, 24 | .navbar-inverse .navbar-nav>li>a, 25 | .dropdown-menu>li>a { 26 | color: #fff; 27 | } 28 | .dropdown-menu { 29 | border: 0; 30 | background-color: transparent; 31 | } 32 | .dropdown-menu>li>a:focus, 33 | .dropdown-menu>li>a:hover { 34 | color: #fff; 35 | background-color: transparent; 36 | } 37 | .navbar-inverse .navbar-nav>.open>a, 38 | .navbar-inverse .navbar-nav>.open>a:focus, 39 | .navbar-inverse .navbar-nav>.open>a:hover { 40 | background-color: transparent; 41 | } 42 | 43 | .map-outer { 44 | margin-top: -20px; 45 | height: 600px; 46 | width: 100%; 47 | margin-bottom: 15px; 48 | padding-top: 50px; 49 | } 50 | .logo { 51 | width: 20rem; 52 | margin: 0 auto; 53 | display: block; 54 | transition: all 0.1s; 55 | animation: rotate 5s linear infinite; 56 | } 57 | 58 | .map-inner { 59 | font-size: 10rem; 60 | text-align: center; 61 | color: #fff; 62 | transition: all 0.5s; 63 | display: block; 64 | margin: 0 auto; 65 | } 66 | 67 | 68 | .map-desc { 69 | font-size: 2rem; 70 | text-align: center; 71 | color: #fff; 72 | } 73 | /* 背景 */ 74 | .diy-bg { 75 | z-index: -1; 76 | position: fixed; 77 | width: 100%; 78 | height: 100%; 79 | background-size: cover; 80 | } 81 | 82 | 83 | /* API */ 84 | .item-outer { 85 | padding: 0; 86 | padding: 15px; 87 | } 88 | 89 | .item-inner { 90 | display: block; 91 | text-decoration: none; 92 | cursor:pointer; 93 | text-align: center; 94 | color: #fff; 95 | font-size: 2rem; 96 | background: transparent; 97 | color: #fff; 98 | border: 2px solid #fff; 99 | border-radius: 40px; 100 | padding: 0.8rem 2rem; 101 | font: 24px "Margarine", 102 | sans-serif; 103 | outline: none; 104 | cursor: pointer; 105 | position: relative; 106 | transition: 0.2s ease-in-out; 107 | letter-spacing: 2px; 108 | height: 7rem; 109 | } 110 | .item-outer>a:hover { 111 | color: #fff; 112 | transform: translateY(-10px) scale(1.05); 113 | } 114 | 115 | .footer-text, 116 | .footer-text>a, 117 | .footer-text>a:hover { 118 | color: #fff; 119 | } 120 | 121 | .item-inner > span { 122 | display: block; 123 | } 124 | .item-inner .stat { 125 | font-size: 1.5rem; 126 | } 127 | .item-inner .glyphicon { 128 | font-size: 1.5rem; 129 | } 130 | 131 | .navbar-bottom { 132 | margin-top: 30px; 133 | } 134 | 135 | @media (max-width: 767px) { 136 | .map-outer { 137 | height: 300px; 138 | padding-top: 25px; 139 | } 140 | .logo { 141 | width: 10rem; 142 | } 143 | .map-inner { 144 | font-size: 5rem; 145 | } 146 | .map-desc { 147 | font-size: 1.5rem; 148 | } 149 | .navbar-inverse .navbar-nav .open .dropdown-menu>li>a { 150 | color: #fff; 151 | } 152 | .item-inner { 153 | height: 5.4rem; 154 | font-size: 1.8rem; 155 | padding: 0.6rem 2rem; 156 | } 157 | .item-inner .stat { 158 | font-size: 1.2rem; 159 | } 160 | .item-inner .glyphicon { 161 | font-size: 1.2rem; 162 | } 163 | } 164 | 165 | /* logo旋转 */ 166 | @keyframes rotate { 167 | 0% { 168 | transform: rotate(0); 169 | } 170 | 171 | 50% { 172 | transform: rotate(180deg); 173 | } 174 | 175 | 100% { 176 | transform: rotate(360deg); 177 | } 178 | } 179 | 180 | 181 | /* 滚动条 */ 182 | ::-webkit-scrollbar { 183 | width: 8px; 184 | height: 6px; 185 | } 186 | 187 | ::-webkit-scrollbar-thumb { 188 | border-radius: 4px; 189 | background-color: #cbcbcb; 190 | } 191 | 192 | ::-webkit-scrollbar-thumb:hover { 193 | background-color: #bbbbbb; 194 | } 195 | 196 | ::-webkit-scrollbar-track-piece { 197 | background: #eee; 198 | } 199 | 200 | 201 | /* 加载动画 */ 202 | .loading { 203 | display: none 204 | } 205 | 206 | .loading { 207 | height: 100%; 208 | width: 100%; 209 | position: fixed; 210 | top: 0; 211 | left: 0; 212 | z-index: 999999; 213 | /* background-color: rgba(250, 250, 250, .9) */ 214 | } 215 | 216 | .loading img { 217 | width: 280px; 218 | height: 210px; 219 | position: relative; 220 | top: 45%; 221 | left: 50%; 222 | margin-left: -140px; 223 | margin-top: -105px; 224 | } 225 | 226 | #loader { 227 | display: block; 228 | position: relative; 229 | left: 50%; 230 | top: 50%; 231 | width: 150px; 232 | height: 150px; 233 | margin: -75px 0 0 -75px; 234 | border-radius: 50%; 235 | border: 3px solid transparent; 236 | border-top-color: #ff5a5a; 237 | -webkit-animation: spin 1s linear infinite; 238 | animation: spin 1s linear infinite; 239 | } 240 | 241 | #loader:before { 242 | content: ""; 243 | position: absolute; 244 | top: 5px; 245 | left: 5px; 246 | right: 5px; 247 | bottom: 5px; 248 | border-radius: 50%; 249 | border: 3px solid transparent; 250 | border-top-color: #5af33f; 251 | -webkit-animation: spin 3s linear infinite; 252 | animation: spin 3s linear infinite; 253 | } 254 | 255 | #loader:after { 256 | content: ""; 257 | position: absolute; 258 | top: 15px; 259 | left: 15px; 260 | right: 15px; 261 | bottom: 15px; 262 | border-radius: 50%; 263 | border: 3px solid transparent; 264 | border-top-color: #6dc9ff; 265 | -webkit-animation: spin 2s linear infinite; 266 | animation: spin 2s linear infinite; 267 | } 268 | 269 | @-webkit-keyframes spin { 270 | 0% { 271 | -webkit-transform: rotate(0deg); 272 | -ms-transform: rotate(0deg); 273 | transform: rotate(0deg); 274 | } 275 | 276 | 100% { 277 | -webkit-transform: rotate(360deg); 278 | -ms-transform: rotate(360deg); 279 | transform: rotate(360deg); 280 | } 281 | } 282 | 283 | @keyframes spin { 284 | 0% { 285 | -webkit-transform: rotate(0deg); 286 | -ms-transform: rotate(0deg); 287 | transform: rotate(0deg); 288 | } 289 | 290 | 100% { 291 | -webkit-transform: rotate(360deg); 292 | -ms-transform: rotate(360deg); 293 | transform: rotate(360deg); 294 | } 295 | } -------------------------------------------------------------------------------- /public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BWmelon/BWmelonApi/482f7ffdf55d3ef104840a9fc9c500e8a7e7c8bf/public/favicon.ico -------------------------------------------------------------------------------- /public/icp.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | icp备案查询api 15 | 16 | 17 | 18 |
19 | 20 |
21 | 22 |
23 | 52 |
53 | 54 | 55 |
56 |
57 | 58 |
59 |
60 |

接口说明

61 |
62 |
63 | 获取域名的icp备案信息 64 |
65 |
66 |
67 |
68 |

请求方式

69 |
70 |
71 | GET 72 |
73 |
74 | 75 |
76 |
77 |

请求地址

78 |
79 |
80 |
https://api.no0a.cn/api/icp/query?domain=
81 |
82 |
83 | 84 |
85 |
参数说明
86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 |
参数说明
domain需要获取信息的域名
status返回的状态码
info返回的备案信息
name主办单位名称
properties主办单位性质
icp网站备案/许可证号
title网站名称
people网站负责人
time审核时间
msg返回的错误信息
132 |
133 |
134 |
135 |

请求示例

136 |
137 |
138 |
https://api.no0a.cn/api/icp/query?domain=qq.com
139 |
140 |
141 |
142 |
143 |

返回示例

144 |
145 |
146 |
147 | {
148 |     "status": 1,
149 |     "info": {
150 |         "name": "深圳市腾讯计算机系统有限公司",
151 |         "properties": "企业",
152 |         "icp": "粤B2-20090059-5",
153 |         "title": "腾讯网",
154 |         "people": "--",
155 |         "time": "2019/8/1 0:00:00"
156 |     }
157 | }
158 |                     
159 | 160 |
161 |
162 | 163 |
164 |
165 | 166 | 167 | 178 | 179 | 180 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | -------------------------------------------------------------------------------- /public/imgs/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BWmelon/BWmelonApi/482f7ffdf55d3ef104840a9fc9c500e8a7e7c8bf/public/imgs/logo.png -------------------------------------------------------------------------------- /public/imgs/map.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BWmelon/BWmelonApi/482f7ffdf55d3ef104840a9fc9c500e8a7e7c8bf/public/imgs/map.jpg -------------------------------------------------------------------------------- /public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 大西瓜api 16 | 17 | 18 | 19 |
20 | 21 |
22 | 23 |
24 | 53 |
54 | 55 | 56 |
57 | 58 |
59 | 60 |
大西瓜API
61 |
————简洁、快速、高效的API聚合平台————
62 |
63 |
64 | 73 | 82 | 91 | 100 | 109 | 118 | 127 | 136 | 145 | 154 |
155 | 156 |
157 | 158 | 159 | 170 | 171 | 172 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | -------------------------------------------------------------------------------- /public/js/index.js: -------------------------------------------------------------------------------- 1 | $(function () { 2 | particlesJS("particles-js", { 3 | particles: { 4 | number: { 5 | value: 120, 6 | density: { 7 | enable: true, 8 | value_area: 800 9 | } 10 | }, 11 | color: { 12 | value: "#ffffff" 13 | }, 14 | shape: { 15 | type: "circle", 16 | stroke: { 17 | width: 0, 18 | color: "#000000" 19 | }, 20 | polygon: { 21 | nb_sides: 5 22 | }, 23 | image: { 24 | src: "img/github.svg", 25 | width: 100, 26 | height: 100 27 | } 28 | }, 29 | opacity: { 30 | value: .5, 31 | random: false, 32 | anim: { 33 | enable: false, 34 | speed: 1, 35 | opacity_min: .1, 36 | sync: false 37 | } 38 | }, 39 | size: { 40 | value: 1, 41 | random: true, 42 | anim: { 43 | enable: false, 44 | speed: 20, 45 | size_min: .1, 46 | sync: false 47 | } 48 | }, 49 | line_linked: { 50 | enable: true, 51 | distance: 40, 52 | color: "#fff", 53 | opacity: 1, 54 | width: 1 55 | }, 56 | move: { 57 | enable: true, 58 | speed: 3, 59 | direction: "none", 60 | random: false, 61 | straight: false, 62 | out_mode: "out", 63 | attract: { 64 | enable: false, 65 | rotateX: 600, 66 | rotateY: 1200 67 | } 68 | } 69 | }, 70 | interactivity: { 71 | detect_on: "canvas", 72 | events: { 73 | onhover: { 74 | enable: true, 75 | mode: "grab" 76 | }, 77 | onclick: { 78 | enable: true, 79 | mode: "push" 80 | }, 81 | resize: true 82 | }, 83 | modes: { 84 | grab: { 85 | distance: 120, 86 | line_linked: { 87 | opacity: 1 88 | } 89 | }, 90 | bubble: { 91 | distance: 400, 92 | size: 40, 93 | duration: 2, 94 | opacity: 8, 95 | speed: 3 96 | }, 97 | repulse: { 98 | distance: 300 99 | }, 100 | push: { 101 | particles_nb: 4 102 | }, 103 | remove: { 104 | particles_nb: 2 105 | } 106 | } 107 | }, 108 | retina_detect: true, 109 | config_demo: { 110 | hide_card: false, 111 | background_color: "#b61924", 112 | background_image: "", 113 | background_position: "50% 50%", 114 | background_repeat: "no-repeat", 115 | background_size: "cover" 116 | } 117 | }); 118 | $(document).pjax('a[data-pjax]', '#pjax-content', { 119 | fragment: '#pjax-content', 120 | timeout: 8000, 121 | type: 'GET' 122 | }); 123 | $(document).on('pjax:send', function () { 124 | $(".loading").css("display", "block"); 125 | }); 126 | $(document).on('pjax:complete', function () { 127 | $(".loading").css("display", "none"); 128 | $.ajax({ 129 | url: "/api/statistic", 130 | dataType: "JSON", 131 | success: function (e) { 132 | $("#tinyurl").text(e.tinyurl); 133 | $("#longurl").text(e.longurl); 134 | $("#qrcode").text(e.qrcode); 135 | $("#qrdecode").text(e.qrdecode); 136 | $("#sitetitle").text(e.sitetitle); 137 | $("#icp").text(e.icp); 138 | $("#cloudmusic").text(e.cloudmusic); 139 | $("#qqinfo").text(e.qqinfo); 140 | $("#onenote").text(e.onenote); 141 | $("#bing").text(e.bing); 142 | $(".stat").countUp({ 143 | time: 1000, 144 | delay: 20 145 | }) 146 | } 147 | }) 148 | }); 149 | $.ajax({ 150 | url: "/api/statistic", 151 | dataType:"JSON", 152 | success: function(e) { 153 | $("#tinyurl").text(e.tinyurl); 154 | $("#longurl").text(e.longurl); 155 | $("#qrcode").text(e.qrcode); 156 | $("#qrdecode").text(e.qrdecode); 157 | $("#sitetitle").text(e.sitetitle); 158 | $("#icp").text(e.icp); 159 | $("#cloudmusic").text(e.cloudmusic); 160 | $("#qqinfo").text(e.qqinfo); 161 | $("#onenote").text(e.onenote); 162 | $("#bing").text(e.bing); 163 | $(".stat").countUp({ 164 | time: 1000, 165 | delay: 20 166 | }) 167 | } 168 | }) 169 | 170 | }) 171 | -------------------------------------------------------------------------------- /public/js/jquery.countup.min.js: -------------------------------------------------------------------------------- 1 | !function(t){"use strict";t.fn.countUp=function(e){var a=t.extend({time:2e3,delay:10},e);return this.each(function(){var e=t(this),n=a,u=function(){e.data("counterupTo")||e.data("counterupTo",e.text());var t=parseInt(e.data("counter-time"))>0?parseInt(e.data("counter-time")):n.time,a=parseInt(e.data("counter-delay"))>0?parseInt(e.data("counter-delay")):n.delay,u=t/a,r=e.data("counterupTo"),o=[r],c=/[0-9]+,[0-9]+/.test(r);r=r.replace(/,/g,"");for(var d=(/^[0-9]+$/.test(r),/^[0-9]+\.[0-9]+$/.test(r)),s=d?(r.split(".")[1]||[]).length:0,i=u;i>=1;i--){var p=parseInt(Math.round(r/u*i));if(d&&(p=parseFloat(r/u*i).toFixed(s)),c)for(;/(\d+)(\d{3})/.test(p.toString());)p=p.toString().replace(/(\d+)(\d{3})/,"$1,$2");o.unshift(p)}e.data("counterup-nums",o),e.text("0");var f=function(){e.text(e.data("counterup-nums").shift()),e.data("counterup-nums").length?setTimeout(e.data("counterup-func"),a):(delete e.data("counterup-nums"),e.data("counterup-nums",null),e.data("counterup-func",null))};e.data("counterup-func",f),setTimeout(e.data("counterup-func"),a)};e.waypoint(u,{offset:"100%",triggerOnce:!0})})}}(jQuery); -------------------------------------------------------------------------------- /public/longurl.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 短网址还原api 15 | 16 | 17 | 18 |
19 | 20 |
21 | 22 |
23 | 52 |
53 | 54 | 55 |
56 |
57 | 58 |
59 |
60 |

接口说明

61 |
62 |
63 | 将短网址还原成长网址,支持三百多种短网址还原 64 |
65 |
66 |
67 |
68 |

请求方式

69 |
70 |
71 | GET 72 |
73 |
74 | 75 |
76 |
77 |

请求地址

78 |
79 |
80 |
https://api.no0a.cn/api/longurl/query?tinyurl=
81 |
82 |
83 | 84 |
85 |
参数说明
86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 |
参数说明
tinyurl需要还原的短网址
status返回的状态码
longurl返回的长网址
msg返回的错误信息
108 |
109 |
110 |
111 |

请求示例

112 |
113 |
114 |
https://api.no0a.cn/api/longurl/query?tinyurl=https://url.cn/518YFDl
115 |
116 |
117 |
118 |
119 |

返回示例

120 |
121 |
122 |
123 | {
124 |     "status": 1,
125 |     "longurl": "https://api.no0a.cn"
126 | }
127 |                     
128 | 129 |
130 |
131 | 132 |
133 |
134 | 135 | 136 | 147 | 148 | 149 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | -------------------------------------------------------------------------------- /public/onenote.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 一言api 15 | 16 | 17 | 18 |
19 | 20 |
21 | 22 |
23 | 52 |
53 | 54 | 55 |
56 |
57 | 58 |
59 |
60 |

接口说明

61 |
62 |
63 | 随机获取一言,共三千多条数据 64 |
65 |
66 |
67 |
68 |

请求方式

69 |
70 |
71 | GET 72 |
73 |
74 | 75 |
76 |
77 |

请求地址

78 |
79 |
80 |
https://api.no0a.cn/api/onenote/query
81 |
82 |
83 | 84 |
85 |
参数说明
86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 |
参数说明
status返回的状态码
onenote返回的一言
msg返回的错误信息
104 |
105 |
106 |
107 |

请求示例

108 |
109 |
110 |
https://api.no0a.cn/api/onenote/query
111 |
112 |
113 |
114 |
115 |

返回示例

116 |
117 |
118 |
119 | {
120 |     "status": 1,
121 |     "onenote": "你说你会爱我一辈子,我真傻,居然忘了问是这辈子还是下辈子。"
122 | }
123 |                     
124 | 125 |
126 |
127 | 128 |
129 |
130 | 131 | 132 | 143 | 144 | 145 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | -------------------------------------------------------------------------------- /public/qqinfo.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | QQ资料获取api 15 | 16 | 17 | 18 |
19 | 20 |
21 | 22 |
23 | 52 |
53 | 54 | 55 |
56 |
57 | 58 |
59 |
60 |

接口说明

61 |
62 |
63 | 获取qq的昵称和头像 64 |
65 |
66 |
67 |
68 |

请求方式

69 |
70 |
71 | GET 72 |
73 |
74 | 75 |
76 |
77 |

请求地址

78 |
79 |
80 |
https://api.no0a.cn/api/qqinfo/qq
81 |
82 |
83 | 84 |
85 |
参数说明
86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 |
参数说明
qq需要获取信息的qq号
status返回的状态码
qqinfo返回的qq信息
nicknameQQ昵称
qqavatarQQ头像地址
msg返回的错误信息
116 |
117 |
118 |
119 |

请求示例

120 |
121 |
122 |
https://api.no0a.cn/api/qqinfo/10001
123 |
124 |
125 |
126 |
127 |

返回示例

128 |
129 |
130 |
131 | {
132 |     "status": 1,
133 |     "qqinfo": {
134 |         "nickname": "pony",
135 |         "qqavatar": "http://q1.qlogo.cn/g?b=qq&s=640&nk=10001"
136 |     }
137 | }
138 |                     
139 | 140 |
141 |
142 | 143 |
144 |
145 | 146 | 147 | 158 | 159 | 160 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | -------------------------------------------------------------------------------- /public/qrcode.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 二维码生成api 15 | 16 | 17 | 18 |
19 | 20 |
21 | 22 |
23 | 52 |
53 | 54 | 55 |
56 |
57 | 58 |
59 |
60 |

接口说明

61 |
62 |
63 | 将网址或者文字生成二维码 64 |
65 |
66 |
67 |
68 |

请求方式

69 |
70 |
71 | GET 72 |
73 |
74 | 75 |
76 |
77 |

请求地址

78 |
79 |
80 |
https://api.no0a.cn/api/qrcode/query?url=
81 |
82 |
83 | 84 |
85 |
参数说明
86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 |
参数说明
url需要生成二维码的链接或者文字
status返回的状态码
msg返回的错误信息
104 |
105 |
106 |
107 |

请求示例

108 |
109 |
110 |
https://api.no0a.cn/api/qrcode/query?url=https://api.no0a.cn
111 |
112 |
113 |
114 |
115 |

返回示例

116 |
117 |
118 |
119 | 直接返回二维码
120 |                     
121 | 122 |
123 |
124 | 125 |
126 |
127 | 128 | 129 | 140 | 141 | 142 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | -------------------------------------------------------------------------------- /public/qrdecode.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 二维码识别解析api 15 | 16 | 17 | 18 |
19 | 20 |
21 | 22 |
23 | 52 |
53 | 54 | 55 |
56 |
57 | 58 |
59 |
60 |

接口说明

61 |
62 |
63 | 将二维码内容解析出来 64 |
65 |
66 |
67 |
68 |

请求方式

69 |
70 |
71 | GET 72 |
73 |
74 | 75 |
76 |
77 |

请求地址

78 |
79 |
80 |
https://api.no0a.cn/api/qrdecode/query?imgurl=
81 |
82 |
83 | 84 |
85 |
参数说明
86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 |
参数说明
imgurl需要解析的二维码图片
status返回的状态码
qrurl返回的二维码地址
msg返回的错误信息
108 |
109 |
110 |
111 |

请求示例

112 |
113 |
114 |
https://api.no0a.cn/api/qrdecode/query?imgurl=https://imgs.bwmelon.com/20190803222039.png
115 |
116 |
117 |
118 |
119 |

返回示例

120 |
121 |
122 |
123 | {
124 |     "status": 1,
125 |     "qrurl":"https://i.qianbao.qq.com/wallet/sqrcode.htm?m=tenpay&f=wallet&a=1&ac=CAEQl4jHtQUYz93y6AU%3D_xxx_sign&u=1454490647&n=%E6%89%93%EF%BC%8C%E6%89%93%E4%B8%AA%E5%A4%A7%E8%A5%BF%E7%93%9C%E3%80%80"
126 | }
127 |                     
128 | 129 |
130 |
131 | 132 |
133 |
134 | 135 | 136 | 147 | 148 | 149 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | -------------------------------------------------------------------------------- /public/sitetitle.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 网站标题获取api 15 | 16 | 17 | 18 |
19 | 20 |
21 | 22 |
23 | 52 |
53 | 54 | 55 |
56 |
57 | 58 |
59 |
60 |

接口说明

61 |
62 |
63 | 获取指定页面的标题 64 |
65 |
66 |
67 |
68 |

请求方式

69 |
70 |
71 | GET 72 |
73 |
74 | 75 |
76 |
77 |

请求地址

78 |
79 |
80 |
https://api.no0a.cn/api/sitetitle/query?url=
81 |
82 |
83 | 84 |
85 |
参数说明
86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 |
参数说明
url需要获取标题的页面地址
status返回的状态码
title返回的网页标题
msg返回的错误信息
108 |
109 |
110 |
111 |

请求示例

112 |
113 |
114 |
https://api.no0a.cn/api/sitetitle/query?url=https://qr.no0a.cn
115 |
116 |
117 |
118 |
119 |

返回示例

120 |
121 |
122 |
123 | {
124 |     "status": 1,
125 |     "title": "大西瓜三合一收款码"
126 | }
127 |                     
128 | 129 |
130 |
131 | 132 |
133 |
134 | 135 | 136 | 147 | 148 | 149 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | -------------------------------------------------------------------------------- /public/static/particles.json: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BWmelon/BWmelonApi/482f7ffdf55d3ef104840a9fc9c500e8a7e7c8bf/public/static/particles.json -------------------------------------------------------------------------------- /public/tinyurl.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 短网址生成api 15 | 16 | 17 | 18 |
19 | 20 |
21 | 22 |
23 | 52 |
53 | 54 | 55 |
56 |
57 | 58 |
59 |
60 |

接口说明

61 |
62 |
63 | 将长网址转成短网址,支持url.cn和t.cn短网址 64 |
65 |
66 |
67 |
68 |

请求方式

69 |
70 |
71 | GET 72 |
73 |
74 | 75 |
76 |
77 |

请求地址

78 |
79 |
80 |
https://api.no0a.cn/api/tinyurl/urlcn/?longurl=
81 |
82 |
83 |
https://api.no0a.cn/api/tinyurl/tcn/?longurl=
84 |
85 |
86 | 87 |
88 |
参数说明
89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 |
参数说明
longurl需要缩短的长网址
status返回的状态码
tinyurl返回的短网址
msg返回的错误信息
111 |
112 |
113 |
114 |

请求示例

115 |
116 |
117 |
https://api.no0a.cn/api/tinyurl/urlcn/?longurl=https://api.no0a.cn
118 |
119 |
120 |
121 |
122 |

返回示例

123 |
124 |
125 |
126 | {
127 |     "status": 1,
128 |     "tinyurl": "https://url.cn/518YFDl"
129 | }
130 |                     
131 | 132 |
133 |
134 | 135 |
136 |
137 | 138 | 139 | 149 | 150 | 151 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | -------------------------------------------------------------------------------- /routes/api/bing.js: -------------------------------------------------------------------------------- 1 | const express = require("express"); 2 | const router = express.Router(); 3 | const request = require("request"); 4 | const Core = require("../../core/function"); 5 | const core = new Core(); 6 | 7 | router.get("/:day", (req, res) => { 8 | if (!req.params.day) { 9 | res.json({ 10 | status: 3, 11 | msg: "壁纸日期不能为空" 12 | }) 13 | } else if (req.params.day < 0 || req.params.day > 7) { 14 | res.json({ 15 | status: 4, 16 | msg: "壁纸日期应为0-8" 17 | }) 18 | } else { 19 | bing(req.params.day) 20 | .then(req => { 21 | res.json({ 22 | status: 1, 23 | bing: req 24 | }) 25 | }) 26 | .catch(req => { 27 | res.json({ 28 | status: 2, 29 | msg: "壁纸获取失败" 30 | }) 31 | }) 32 | } 33 | core.statAdd("bing"); 34 | }); 35 | 36 | function bing(day) { 37 | // https://cn.bing.com/HPImageArchive.aspx?format=js&idx=0&n=1 38 | return new Promise((resolve, reject) => { 39 | let opts = { 40 | url: "https://cn.bing.com/HPImageArchive.aspx?format=js&n=1&idx=" + day, 41 | method: "GET", 42 | headers: {} 43 | }; 44 | request(opts, function (error, response, body) { 45 | if (!error && response.statusCode == 200) { 46 | if (day >= 0 && day <= 7) { 47 | let ret = JSON.parse(body) 48 | let url = "http://s.cn.bing.net" + ret.images[0].url; 49 | let copyright = ret.images[0].copyright; 50 | resolve({ 51 | url, 52 | copyright 53 | }) 54 | } else { 55 | reject({ 56 | msg: "error", 57 | }) 58 | } 59 | } else { 60 | reject(error); 61 | } 62 | }); 63 | 64 | 65 | }); 66 | 67 | }; 68 | 69 | 70 | module.exports = router; -------------------------------------------------------------------------------- /routes/api/cloudmusic.js: -------------------------------------------------------------------------------- 1 | const express = require("express"); 2 | const router = express.Router(); 3 | const NeteaseMusic = require("simple-netease-cloud-music"); 4 | const nm = new NeteaseMusic() 5 | const Core = require("../../core/function"); 6 | const core = new Core(); 7 | 8 | 9 | // 歌曲搜索 10 | router.get("/search/:key", (req, res) => { 11 | if (!req.params.key) { 12 | res.json({ 13 | status: 2, 14 | msg: "搜索词不能为空" 15 | }) 16 | } else { 17 | nm.search(req.params.key).then(data => { 18 | if (data.result.songCount) { 19 | // 歌曲名 20 | let results = []; 21 | for (const i in data.result.songs) { 22 | if (data.result.songs.hasOwnProperty(i)) { 23 | const name = data.result.songs[i].name; 24 | const id = data.result.songs[i].id; 25 | // 作者 26 | let artist = []; 27 | for (const j in data.result.songs[i].ar) { 28 | if (data.result.songs[i].ar.hasOwnProperty(j)) { 29 | const element = data.result.songs[i].ar[j].name; 30 | const arr = { 31 | "name": element 32 | }; 33 | artist.push(arr); 34 | } 35 | } 36 | results.push({ 37 | name, 38 | id, 39 | artist 40 | }); 41 | } 42 | } 43 | res.json({ 44 | status: 1, 45 | results 46 | }) 47 | } else { 48 | res.json({ 49 | status: 3, 50 | msg: "歌曲获取失败" 51 | }) 52 | } 53 | }) 54 | } 55 | core.statAdd("cloudmusic"); 56 | }); 57 | 58 | 59 | 60 | // 歌曲url获取 61 | router.get("/url/:id", (req, res) => { 62 | if (!req.params.id) { 63 | res.json({ 64 | status: 2, 65 | msg: "歌曲id不能为空" 66 | }) 67 | } else { 68 | nm.url(req.params.id).then(data => { 69 | if(data.data[0].url) { 70 | res.json({ 71 | status: 1, 72 | musicurl: data.data[0].url 73 | }) 74 | } else { 75 | res.json({ 76 | status: 3, 77 | msg: "url获取失败" 78 | }) 79 | } 80 | }) 81 | } 82 | core.statAdd("cloudmusic"); 83 | }); 84 | 85 | // 歌曲信息获取 86 | router.get("/info/:id", (req, res) => { 87 | if (!req.params.id) { 88 | res.json({ 89 | status: 2, 90 | msg: "歌曲id不能为空" 91 | }) 92 | } else { 93 | nm.song(req.params.id).then(data => { 94 | if (data.songs.length) { 95 | let artist = []; 96 | for (const i in data.songs[0].ar) { 97 | if (data.songs[0].ar.hasOwnProperty(i)) { 98 | const element = data.songs[0].ar[i].name; 99 | const arr = {"name": element}; 100 | artist.push(arr); 101 | } 102 | } 103 | res.json({ 104 | status: 1, 105 | musicinfo: { 106 | name: data.songs[0].name, 107 | artist: artist 108 | } 109 | }) 110 | } else { 111 | res.json({ 112 | status: 3, 113 | msg: "歌曲获取失败" 114 | }) 115 | } 116 | }) 117 | } 118 | core.statAdd("cloudmusic"); 119 | }); 120 | 121 | 122 | 123 | // 歌曲歌词获取 124 | router.get("/lyric/:id", (req, res) => { 125 | if (!req.params.id) { 126 | res.json({ 127 | status: 2, 128 | msg: "歌曲id不能为空" 129 | }) 130 | } else { 131 | nm.lyric(req.params.id).then(data => { 132 | if(!data.uncollected) { 133 | res.json({ 134 | status: 1, 135 | musiclyric: data.lrc.lyric 136 | }) 137 | } else { 138 | res.json({ 139 | status: 3, 140 | msg: "歌词获取失败" 141 | }) 142 | } 143 | }) 144 | } 145 | core.statAdd("cloudmusic"); 146 | }); 147 | 148 | 149 | // 歌单列表获取 150 | router.get("/playlist/:id", (req, res) => { 151 | if (!req.params.id) { 152 | res.json({ 153 | status: 2, 154 | msg: "歌单id不能为空" 155 | }) 156 | } else { 157 | nm.playlist(req.params.id).then(data => { 158 | if (data.code = 200) { 159 | // 歌曲名 160 | let results = []; 161 | for (const i in data.playlist.tracks) { 162 | if (data.playlist.tracks.hasOwnProperty(i)) { 163 | const name = data.playlist.tracks[i].name; 164 | const id = data.playlist.tracks[i].id; 165 | // 作者 166 | let artist = []; 167 | for (const j in data.playlist.tracks[i].ar) { 168 | if (data.playlist.tracks[i].ar.hasOwnProperty(j)) { 169 | const element = data.playlist.tracks[i].ar[j].name; 170 | const arr = { 171 | "name": element 172 | }; 173 | artist.push(arr); 174 | } 175 | } 176 | results.push({ 177 | name, 178 | id, 179 | artist 180 | }); 181 | } 182 | } 183 | res.json({ 184 | status: 1, 185 | results 186 | }) 187 | } 188 | }) 189 | } 190 | core.statAdd("cloudmusic"); 191 | }); 192 | 193 | module.exports = router; -------------------------------------------------------------------------------- /routes/api/icp.js: -------------------------------------------------------------------------------- 1 | const express = require("express"); 2 | const router = express.Router(); 3 | const request = require("request"); 4 | const cheerio = require("cheerio"); 5 | const Core = require("../../core/function"); 6 | const core = new Core(); 7 | 8 | router.get("/query", (req, res) => { 9 | if (!req.query.domain) { 10 | res.json({ 11 | status: 2, 12 | msg: "域名不能为空" 13 | }) 14 | } else { 15 | icp(req.query.domain) 16 | .then(req => { 17 | res.json({ 18 | status: 1, 19 | info: req 20 | }) 21 | }) 22 | .catch(req => { 23 | res.json({ 24 | status: 3, 25 | msg: "获取备案信息失败" 26 | }) 27 | }) 28 | } 29 | core.statAdd("icp"); 30 | }); 31 | 32 | function icp(domain) { 33 | return new Promise((resolve, reject) => { 34 | let opts = { 35 | url: "http://icp.chinaz.com/" + domain, 36 | method: "get", 37 | headers: { 38 | "content-type": "text/html" 39 | } 40 | } 41 | request(opts, function (error, response, body) { 42 | if (!error && response.statusCode == 200) { 43 | $ = cheerio.load(body); 44 | if ($("#first p").eq(0).text()) { 45 | let name = $("#first p").eq(0).text(); 46 | name = name.replace("使用高级查询纠正信息", ""); 47 | let properties = $("#first p").eq(1).text(); 48 | let icp = $("#first p").eq(2).text(); 49 | icp = icp.replace("查看截图", ""); 50 | let title = $("#first p").eq(3).text(); 51 | let people = $("#first p").eq(4).text(); 52 | let time = $("#first p").eq(7).text(); 53 | resolve({ 54 | name, 55 | properties, 56 | icp, 57 | title, 58 | people, 59 | time 60 | }); 61 | } else { 62 | reject("failed"); 63 | } 64 | } else { 65 | reject(error); 66 | } 67 | }) 68 | }); 69 | 70 | }; 71 | 72 | 73 | module.exports = router; -------------------------------------------------------------------------------- /routes/api/longurl.js: -------------------------------------------------------------------------------- 1 | const express = require("express"); 2 | const router = express.Router(); 3 | const request = require("request"); 4 | const cheerio = require("cheerio"); 5 | const Core = require("../../core/function"); 6 | const core = new Core(); 7 | 8 | router.get("/query", (req, res) => { 9 | if (!req.query.tinyurl) { 10 | res.json({ 11 | status: 2, 12 | msg: "短网址不能为空" 13 | }) 14 | } else { 15 | longurl(req.query.tinyurl) 16 | .then(req => { 17 | res.json({ 18 | status: 1, 19 | longurl: req 20 | }) 21 | }) 22 | .catch(req => { 23 | res.json({ 24 | status: 3, 25 | msg: "短网址还原失败" 26 | }) 27 | }) 28 | } 29 | core.statAdd("longurl"); 30 | }); 31 | 32 | function longurl(tinyurl) { 33 | return new Promise((resolve, reject) => { 34 | let opts = { 35 | url: "https://duanwangzhihuanyuan.51240.com/web_system/51240_com_www/system/file/duanwangzhihuanyuan/get/?ajaxtimestamp=" + new Date().getTime(), 36 | method: "POST", 37 | form: { 38 | turl: tinyurl 39 | }, 40 | headers: { 41 | "content-type": "text/html" 42 | } 43 | } 44 | request(opts, function (error, response, body) { 45 | if (!error && response.statusCode == 200) { 46 | $ = cheerio.load(body); 47 | if ($("a").text()) { 48 | resolve($("a").text()); 49 | } else { 50 | reject("failed"); 51 | } 52 | } else { 53 | reject(error); 54 | } 55 | }) 56 | }); 57 | 58 | }; 59 | 60 | 61 | module.exports = router; -------------------------------------------------------------------------------- /routes/api/onenote.js: -------------------------------------------------------------------------------- 1 | const express = require("express"); 2 | const router = express.Router(); 3 | const readline = require('readline'); 4 | const fs = require("fs"); 5 | const Core = require("../../core/function"); 6 | const core = new Core(); 7 | 8 | router.get("/query", (req, res) => { 9 | onenote(process.cwd() + '/static/files/onenote.txt') 10 | .then(req => { 11 | res.json({ 12 | status: 1, 13 | onenote: req 14 | }) 15 | }) 16 | .catch(req => { 17 | res.json({ 18 | status: 3, 19 | msg: "一言获取失败" 20 | }) 21 | }) 22 | core.statAdd("onenote"); 23 | }); 24 | 25 | function onenote(filepath) { 26 | return new Promise((resolve, reject) => { 27 | const rl = readline.createInterface({ 28 | input: fs.createReadStream(filepath) 29 | }); 30 | let arr = new Array(); 31 | rl.on('line', (line) => { 32 | arr.push(line); 33 | }) 34 | rl.on("close", ()=> { 35 | if (arr[parseInt(Math.random() * (arr.length - 1), 10)]) { 36 | resolve(arr[parseInt(Math.random() * (arr.length - 1), 10)]); 37 | } else { 38 | reject("failed") 39 | } 40 | 41 | }) 42 | }); 43 | 44 | }; 45 | 46 | 47 | module.exports = router; -------------------------------------------------------------------------------- /routes/api/qqinfo.js: -------------------------------------------------------------------------------- 1 | const express = require("express"); 2 | const router = express.Router(); 3 | const request = require("request"); 4 | const Core = require("../../core/function"); 5 | const core = new Core(); 6 | 7 | router.get("/:qq", (req, res) => { 8 | if (!req.params.qq) { 9 | res.json({ 10 | status: 3, 11 | msg: "QQ号不能为空" 12 | }) 13 | } else { 14 | qqinfo(req.params.qq) 15 | .then(req => { 16 | res.json({ 17 | status: 1, 18 | qqinfo: req 19 | }) 20 | }) 21 | .catch(req => { 22 | res.json({ 23 | status: 2, 24 | msg: req 25 | }) 26 | }) 27 | } 28 | core.statAdd("qqinfo"); 29 | }); 30 | 31 | function qqinfo(qq) { 32 | // http://q1.qlogo.cn/g?b=qq&s=640&nk=qq 33 | // http://r.qzone.qq.com/fcg-bin/cgi_get_portrait.fcg?uins=qq 34 | return new Promise((resolve, reject) => { 35 | let opts = { 36 | url: "http://r.qzone.qq.com/fcg-bin/cgi_get_portrait.fcg?uins=" + qq, 37 | method: "GET", 38 | headers: { 39 | } 40 | }; 41 | request(opts, function (error, response, body) { 42 | if (!error && response.statusCode == 200) { 43 | if (body.indexOf("error") == -1) { 44 | let nickname = body; 45 | nickname = nickname.replace(nickname.slice(0, 17), ""); 46 | nickname = nickname.replace(nickname.slice(-1), ""); 47 | let obj = JSON.parse(nickname); 48 | resolve({ 49 | nickname: obj[qq][6], 50 | qqavatar: "http://q1.qlogo.cn/g?b=qq&s=640&nk=" + qq 51 | }) 52 | } else { 53 | reject({ 54 | msg: "号码输入错误", 55 | }) 56 | } 57 | } else { 58 | reject(error); 59 | } 60 | }); 61 | 62 | 63 | }); 64 | 65 | }; 66 | 67 | 68 | module.exports = router; -------------------------------------------------------------------------------- /routes/api/qrcode.js: -------------------------------------------------------------------------------- 1 | const express = require("express"); 2 | const router = express.Router(); 3 | const qr = require('qr-image'); 4 | const Core = require("../../core/function"); 5 | const core = new Core(); 6 | 7 | 8 | 9 | router.get("/query", (req, res) => { 10 | if (!req.query.url) { 11 | res.json({ 12 | status: 2, 13 | msg: "生成内容不能为空" 14 | }) 15 | } else { 16 | res.end(qr.imageSync(req.query.url)) 17 | } 18 | core.statAdd("qrcode"); 19 | }); 20 | 21 | module.exports = router; -------------------------------------------------------------------------------- /routes/api/qrdecode.js: -------------------------------------------------------------------------------- 1 | const express = require("express"); 2 | const router = express.Router(); 3 | const request = require("request"); 4 | const qrDecode = require('qr-decode/server'); 5 | const Core = require("../../core/function"); 6 | const core = new Core(); 7 | 8 | router.get("/query", (req, res) => { 9 | if (!req.query.imgurl) { 10 | res.json({ 11 | status: 2, 12 | msg: "图片地址不能为空" 13 | }) 14 | } else { 15 | qrdecode(req.query.imgurl) 16 | .then(req => { 17 | res.json({ 18 | status: 1, 19 | qrurl: req 20 | }) 21 | }) 22 | .catch(req => { 23 | res.json({ 24 | status: 3, 25 | msg: "二维码解析失败" 26 | }) 27 | }) 28 | } 29 | core.statAdd("qrdecode"); 30 | }); 31 | 32 | function qrdecode(imgurl) { 33 | return new Promise((resolve, reject) => { 34 | let opts = { 35 | url: imgurl, 36 | encoding: null 37 | } 38 | 39 | request.get(opts, function (err, response, body) { 40 | qrDecode.decodeByBuffer(body).then((res) => { 41 | resolve(res); 42 | 43 | }).catch(err => { 44 | reject(err); 45 | }); 46 | }) 47 | }); 48 | 49 | }; 50 | 51 | 52 | module.exports = router; -------------------------------------------------------------------------------- /routes/api/sitetitle.js: -------------------------------------------------------------------------------- 1 | const express = require("express"); 2 | const router = express.Router(); 3 | const request = require("request"); 4 | const cheerio = require("cheerio"); 5 | const Core = require("../../core/function"); 6 | const core = new Core(); 7 | 8 | router.get("/query", (req, res) => { 9 | if (!req.query.url) { 10 | res.json({ 11 | status: 2, 12 | msg: "网址不能为空" 13 | }) 14 | } else { 15 | let url = req.query.url.indexOf("http") != -1 ? req.query.url : "http://" + req.query.url; 16 | longurl(url) 17 | .then(req => { 18 | res.json({ 19 | status: 1, 20 | title: req 21 | }) 22 | }) 23 | .catch(req => { 24 | res.json({ 25 | status: 3, 26 | msg: "获取网站标题失败" 27 | }) 28 | }) 29 | } 30 | core.statAdd("sitetitle"); 31 | }); 32 | 33 | function longurl(url) { 34 | return new Promise((resolve, reject) => { 35 | let opts = { 36 | url: url, 37 | method: "get", 38 | headers: { 39 | "content-type": "text/html" 40 | } 41 | } 42 | request(opts, function (error, response, body) { 43 | if (!error && response.statusCode == 200) { 44 | $ = cheerio.load(body); 45 | let title = $("title").text(); 46 | if (title) { 47 | resolve(title); 48 | } else { 49 | reject("failed"); 50 | } 51 | } else { 52 | reject(error); 53 | } 54 | }) 55 | }); 56 | 57 | }; 58 | 59 | 60 | module.exports = router; -------------------------------------------------------------------------------- /routes/api/statistic.js: -------------------------------------------------------------------------------- 1 | //调用次数查询 2 | const express = require("express"); 3 | const router = express.Router(); 4 | const Core = require("../../core/function"); 5 | const core = new Core(); 6 | 7 | router.get("/", (req, res) => { 8 | core.statQuery() 9 | .then(stat => { 10 | tinyurl = stat.hasOwnProperty("tinyurl") ? stat.tinyurl : 0; 11 | longurl = stat.hasOwnProperty("longurl") ? stat.longurl : 0; 12 | qrcode = stat.hasOwnProperty("qrcode") ? stat.qrcode : 0; 13 | qrdecode = stat.hasOwnProperty("qrdecode") ? stat.qrdecode : 0; 14 | sitetitle = stat.hasOwnProperty("sitetitle") ? stat.sitetitle : 0; 15 | icp = stat.hasOwnProperty("icp") ? stat.icp : 0; 16 | cloudmusic = stat.hasOwnProperty("cloudmusic") ? stat.cloudmusic : 0; 17 | qqinfo = stat.hasOwnProperty("qqinfo") ? stat.qqinfo : 0; 18 | onenote = stat.hasOwnProperty("onenote") ? stat.onenote : 0; 19 | bing = stat.hasOwnProperty("bing") ? stat.bing : 0; 20 | res.json({ 21 | tinyurl, 22 | longurl, 23 | qrcode, 24 | qrdecode, 25 | sitetitle, 26 | icp, 27 | cloudmusic, 28 | qqinfo, 29 | onenote, 30 | bing 31 | }) 32 | }) 33 | .catch(err => { 34 | console.log(err); 35 | }) 36 | }); 37 | 38 | 39 | 40 | 41 | module.exports = router; -------------------------------------------------------------------------------- /routes/api/tinyurl.js: -------------------------------------------------------------------------------- 1 | const express = require("express"); 2 | const router = express.Router(); 3 | const request = require("request"); 4 | const Core = require("../../core/function"); 5 | const core = new Core(); 6 | 7 | 8 | router.get("/urlcn", (req, res) => { 9 | if (!req.query.longurl) { 10 | res.json({ 11 | status: 2, 12 | msg: "长网址不能为空" 13 | }) 14 | } else { 15 | urlcn(req.query.longurl) 16 | .then((req) => { 17 | res.json({ 18 | status: 1, 19 | tinyurl: req 20 | }); 21 | }) 22 | .catch((err) => { 23 | res.json({ 24 | status: 3, 25 | msg: "短网址生成失败" 26 | }); 27 | }) 28 | } 29 | core.statAdd("tinyurl"); 30 | }); 31 | 32 | router.get("/tcn", (req, res) => { 33 | if (!req.query.longurl) { 34 | res.json({ 35 | status: 2, 36 | msg: "长网址不能为空" 37 | }) 38 | } else { 39 | tcn(req.query.longurl) 40 | .then(function (req) { 41 | res.json({ 42 | status: 1, 43 | tinyurl: req 44 | }); 45 | }) 46 | .catch((err) => { 47 | res.json({ 48 | status: 3, 49 | msg: "短网址生成失败(新浪短网址现已失效)" 50 | }); 51 | }) 52 | } 53 | core.statAdd("tinyurl"); 54 | }); 55 | 56 | function urlcn(url) { 57 | //原api http://sa.sogou.com/gettiny?url= (已失效) 58 | //原api http://dwz.fxw.la/url/url.php? 59 | 60 | return new Promise((resolve, reject) => { 61 | 62 | let opts = { 63 | url: "http://dwz.fxw.la/url/url.php?" + url, 64 | method: "GET", 65 | headers: { 66 | "content-type": "text/plain", 67 | }, 68 | }; 69 | request(opts, function (error, response, body) { 70 | if (!error && response.statusCode == 200) { 71 | let tinyurl = JSON.parse(body); 72 | tinyurl = tinyurl['url_short']; 73 | tinyurl = tinyurl.replace(/http/, "https"); 74 | resolve(tinyurl); 75 | } else { 76 | reject(error); 77 | } 78 | }); 79 | }); 80 | 81 | }; 82 | 83 | function tcn(url) { 84 | //原api https://api.t.sina.com.cn/short_url/shorten.json?source=2849184197&url_long= 85 | return new Promise((resolve, reject) => { 86 | let option = { 87 | url: "https://api.t.sina.com.cn/short_url/shorten.json?source=2849184197&url_long=" + url, 88 | method: "GET", 89 | json: true, 90 | headers: { 91 | "content-type": "application/json", 92 | }, 93 | }; 94 | request(option, function (error, response, body) { 95 | if (!error && response.statusCode == 200) { 96 | tinyurl = body[0].url_short; 97 | tinyurl = tinyurl.replace(/http/, "https"); 98 | resolve(tinyurl); 99 | } 100 | }); 101 | }); 102 | 103 | }; 104 | 105 | module.exports = router; --------------------------------------------------------------------------------