├── 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/")
## 首页截图:

## 使用
```
#安装依赖
$ 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 |
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 | day |
93 | 每日一图时间,0位当前,1为昨天,2为前天,以此类推,最多为前7天 |
94 |
95 |
96 | status |
97 | 返回的状态码 |
98 |
99 |
100 | bing |
101 | 返回的每日一图信息 |
102 |
103 |
104 | url |
105 | 返回的每日一图地址 |
106 |
107 |
108 | copyright |
109 | 返回的每日一图版权 |
110 |
111 |
112 | msg |
113 | 返回的错误信息 |
114 |
115 |
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 |
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 | key |
105 | 歌曲搜索关键词 |
106 |
107 |
108 | id |
109 | 歌曲id或者歌单id |
110 |
111 |
112 | status |
113 | 状态码 |
114 |
115 |
116 | name |
117 | 歌曲名或作者名 |
118 |
119 |
120 | id |
121 | 歌曲id |
122 |
123 |
124 | artist |
125 | 作者名列表 |
126 |
127 |
128 | musicurl |
129 | 歌曲解析地址,格式为mp3 |
130 |
131 |
132 | musiclyric |
133 | 歌词 |
134 |
135 |
136 | musicinfo |
137 | 歌曲信息 |
138 |
139 |
140 | msg |
141 | 返回的错误信息 |
142 |
143 |
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 |
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 | domain |
93 | 需要获取信息的域名 |
94 |
95 |
96 | status |
97 | 返回的状态码 |
98 |
99 |
100 | info |
101 | 返回的备案信息 |
102 |
103 |
104 | name |
105 | 主办单位名称 |
106 |
107 |
108 | properties |
109 | 主办单位性质 |
110 |
111 |
112 | icp |
113 | 网站备案/许可证号 |
114 |
115 |
116 | title |
117 | 网站名称 |
118 |
119 |
120 | people |
121 | 网站负责人 |
122 |
123 |
124 | time |
125 | 审核时间 |
126 |
127 |
128 | msg |
129 | 返回的错误信息 |
130 |
131 |
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 |
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 |
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 | tinyurl |
93 | 需要还原的短网址 |
94 |
95 |
96 | status |
97 | 返回的状态码 |
98 |
99 |
100 | longurl |
101 | 返回的长网址 |
102 |
103 |
104 | msg |
105 | 返回的错误信息 |
106 |
107 |
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 |
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 | status |
93 | 返回的状态码 |
94 |
95 |
96 | onenote |
97 | 返回的一言 |
98 |
99 |
100 | msg |
101 | 返回的错误信息 |
102 |
103 |
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 |
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 | qq |
93 | 需要获取信息的qq号 |
94 |
95 |
96 | status |
97 | 返回的状态码 |
98 |
99 |
100 | qqinfo |
101 | 返回的qq信息 |
102 |
103 |
104 | nickname |
105 | QQ昵称 |
106 |
107 |
108 | qqavatar |
109 | QQ头像地址 |
110 |
111 |
112 | msg |
113 | 返回的错误信息 |
114 |
115 |
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 |
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 | url |
93 | 需要生成二维码的链接或者文字 |
94 |
95 |
96 | status |
97 | 返回的状态码 |
98 |
99 |
100 | msg |
101 | 返回的错误信息 |
102 |
103 |
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 |
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 | imgurl |
93 | 需要解析的二维码图片 |
94 |
95 |
96 | status |
97 | 返回的状态码 |
98 |
99 |
100 | qrurl |
101 | 返回的二维码地址 |
102 |
103 |
104 | msg |
105 | 返回的错误信息 |
106 |
107 |
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 |
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 | url |
93 | 需要获取标题的页面地址 |
94 |
95 |
96 | status |
97 | 返回的状态码 |
98 |
99 |
100 | title |
101 | 返回的网页标题 |
102 |
103 |
104 | msg |
105 | 返回的错误信息 |
106 |
107 |
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 |
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 | longurl |
96 | 需要缩短的长网址 |
97 |
98 |
99 | status |
100 | 返回的状态码 |
101 |
102 |
103 | tinyurl |
104 | 返回的短网址 |
105 |
106 |
107 | msg |
108 | 返回的错误信息 |
109 |
110 |
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;
--------------------------------------------------------------------------------