Merge branch 'main' into 'main'
Some checks failed
Update Docker Hub Description / dockerHubDescription (push) Has been skipped
Node.js CI / Test (14.x) (push) Successful in 9m52s
Node.js CI / Test (16.x) (push) Successful in 9m49s
Node.js CI / Test (18.x) (push) Successful in 9m52s
Node.js CI / Lint (14.x) (push) Failing after 5m10s

feat: 增加API调试界面

See merge request Binaryify/neteasecloudmusicapi!16
This commit is contained in:
binaryify 2024-07-23 01:37:29 +00:00
commit 7e51c9cd5b
9 changed files with 234 additions and 8 deletions

View File

@ -429,6 +429,9 @@ banner({ type: 0 }).then((res) => {
283. 云盘导入歌曲
284. 获取客户端歌曲下载链接 - 新版
285. 当前账号关注的用户/歌手
286. 会员下载歌曲记录
287. 会员本月下载歌曲记录
288. 已购买单曲
## 单元测试

View File

@ -1,3 +1,4 @@
const { cookieToJson } = require('../util/index')
const createOption = require('../util/option.js')
module.exports = (query, request) => {
const method = query.method || 'POST'
@ -6,6 +7,10 @@ module.exports = (query, request) => {
try {
data =
typeof query.data === 'string' ? JSON.parse(query.data) : query.data || {}
if (typeof data.cookie === 'string') {
data.cookie = cookieToJson(data.cookie)
query.cookie = data.cookie
}
} catch (e) {
data = {}
}

11
module/song_downlist.js Normal file
View File

@ -0,0 +1,11 @@
// 会员下载歌曲记录
const createOption = require('../util/option.js')
module.exports = (query, request) => {
const data = {
limit: query.limit || '20',
offset: query.offset || '0',
total: 'true',
}
return request('POST', `/api/member/song/downlist`, data, createOption(query))
}

View File

@ -0,0 +1,16 @@
// 会员本月下载歌曲记录
const createOption = require('../util/option.js')
module.exports = (query, request) => {
const data = {
limit: query.limit || '20',
offset: query.offset || '0',
total: 'true',
}
return request(
'POST',
`/api/member/song/monthdownlist`,
data,
createOption(query),
)
}

View File

@ -0,0 +1,16 @@
// 已购买单曲
const createOption = require('../util/option.js')
module.exports = (query, request) => {
const data = {
limit: query.limit || '20',
offset: query.offset || '0',
total: 'true',
}
return request(
'POST',
`/api/member/song/singledownlist`,
data,
createOption(query),
)
}

127
public/api.html Normal file
View File

@ -0,0 +1,127 @@
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>API 调试界面</title>
<style>
body {
font-family: Arial, sans-serif;
margin: 20px;
display: flex;
flex-direction: column;
min-height: 100vh;
}
.container {
display: flex;
flex-direction: column;
flex-grow: 1;
}
form {
display: flex;
flex-direction: row;
align-items: center;
gap: 10px;
margin-bottom: 10px;
}
input, button {
padding: 10px;
box-sizing: border-box;
flex: 1;
}
button {
background-color: #4CAF50;
color: white;
border: none;
cursor: pointer;
}
.data-result {
display: flex;
flex-direction: row;
flex-grow: 1;
}
.data-result > div {
display: flex;
flex-direction: column;
flex-grow: 1;
padding: 10px;
box-sizing: border-box;
}
.data-result label {
margin-bottom: 10px;
}
#data, #result {
height: 100%;
box-sizing: border-box;
}
#data {
border-right: 1px solid #ccc;
}
</style>
</head>
<body>
<div class="container">
<form onsubmit="event.preventDefault(); sendRequest();">
<label for="uri">uri</label>
<input type="text" id="uri" name="uri" value="/api/song/lyric/v1">
<label for="crypto">crypto</label>
<select id="crypto" name="crypto">
<option value="weapi">weapi</option>
<option value="eapi">eapi</option>
<option value="api">api</option>
<option value="linuxapi">linuxapi</option>
<option value="" selected>(默认)</option>
</select>
<button type="submit">发送</button>
</form>
<div class="data-result">
<div>
<label for="result">result</label>
<textarea id="result" name="result"></textarea>
</div>
<div>
<label for="data">data</label>
<textarea id="data" name="data">
{
"cp": false,
"id": "2058263032",
"kv": 0,
"lv": 0,
"rv": 0,
"tv": 0,
"yrv": 0,
"ytv": 0,
"yv": 0
}</textarea>
</div>
</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
<script>
async function sendRequest() {
document.getElementById('result').value = ""
const uri = document.getElementById('uri').value;
const crypto = document.getElementById('crypto').value;
const data = document.getElementById('data').value;
try {
const res = await axios({
url: `/api?timestamp=${Date.now()}`,
method: 'post',
data: {
uri: uri,
data: JSON.parse(data),
crypto: crypto,
},
});
document.getElementById('result').value = JSON.stringify(res.data, null, 2);
} catch (error) {
document.getElementById('result').value = 'Request failed: ' + error.message;
}
}
</script>
</body>
</html>

View File

@ -301,6 +301,9 @@
283. 云盘导入歌曲
284. 获取客户端歌曲下载链接 - 新版
285. 当前账号关注的用户/歌手
286. 会员下载歌曲记录
287. 会员本月下载歌曲记录
288. 已购买单曲
## 安装
@ -4714,6 +4717,48 @@ bitrate = Math.floor(br / 1000)
**调用例子 :** `/user/follow/mixed?scene=1`
### 会员下载歌曲记录
说明 : 调用此接口, 可获得当前账号会员下载歌曲记录
**可选参数 :**
`limit` : 返回数量 , 默认为 20
`offset` : 偏移数量,用于分页 ,如 :( 页数 -1)\*30, 其中 30 为 limit 的值 , 默认为 0
**接口地址 :** `/song/downlist`
**调用例子 :** `/song/downlist`
### 会员本月下载歌曲记录
说明 : 调用此接口, 可获得当前账号会员本月下载歌曲记录
**可选参数 :**
`limit` : 返回数量 , 默认为 20
`offset` : 偏移数量,用于分页 ,如 :( 页数 -1)\*30, 其中 30 为 limit 的值 , 默认为 0
**接口地址 :** `/song/monthdownlist`
**调用例子 :** `/song/monthdownlist`
### 已购买单曲
说明 : 调用此接口, 可获得当前账号已购买单曲
**可选参数 :**
`limit` : 返回数量 , 默认为 20
`offset` : 偏移数量,用于分页 ,如 :( 页数 -1)\*30, 其中 30 为 limit 的值 , 默认为 0
**接口地址 :** `/song/singledownlist`
**调用例子 :** `/song/singledownlist`
## 离线访问此文档
此文档同时也是 Progressive Web Apps(PWA), 加入了 serviceWorker, 可离线访问

View File

@ -21,6 +21,7 @@
<li>4. <a href="./audio_match_demo/index.html">听歌识曲</a></li>
<li>5. <a href="./cloud.html">云盘上传</a></li>
<li>6. <a href="./eapi_decrypt.html">eapi 参数和返回内容解析</a></li>
<li>7. <a href="./api.html">API 调试界面</a></li>
</ul>
<style>
html,

View File

@ -89,6 +89,16 @@ const createRequest = (method, uri, data = {}, options) => {
encryptData = '',
crypto = options.crypto,
csrfToken = cookie['__csrf'] || ''
if (crypto === '') {
// 加密方式为空,以配置文件的加密方式为准
if (APP_CONF.encrypt) {
crypto = 'eapi'
} else {
crypto = 'api'
}
}
// 根据加密方式加密请求数据目前任意uri都支持四种加密方式
switch (crypto) {
case 'weapi':
@ -112,7 +122,6 @@ const createRequest = (method, uri, data = {}, options) => {
case 'eapi':
case 'api':
case '':
// 两种加密方式都应生成客户端的cookie
const cookie = options.cookie || {}
const header = {
@ -160,13 +169,6 @@ const createRequest = (method, uri, data = {}, options) => {
eapi()
} else if (crypto === 'api') {
api()
} else if (crypto === '') {
// 加密方式为空,以配置文件的加密方式为准
if (APP_CONF.encrypt) {
eapi()
} else {
api()
}
}
break