提交 a7019f5c 编写于 作者: B binaryify

Merge branch 'master' into dev

......@@ -391,14 +391,14 @@
### 2.20.3 | 2018.09.26
- 增加退出登接口
- 增加退出登接口
- 修正 /check/music 的检查逻辑
- 优化 Cookies 设置
- 重构单元测试
[by @nondanee](https://github.com/nondanee)
- 增加 301 需要登提示信息
- 增加 301 需要登提示信息
- 更新文档
......
const fs = require('fs')
const path = require('path')
const request = require('request')
let app
before(() => {
app = require('./app.js')
global.host = 'http://localhost:' + app.server.address().port
request.debug = false
})
after((done) => {
app.server.close(done)
......
......@@ -321,14 +321,14 @@ $ sudo docker run -d -p 3000:3000 netease-music-api
!> 为使用方便,降低门槛, 文档示例接口直接使用了 GET 请求,本项目同时支持 GET/POST 请按实际需求使用 (POST请求url必须添加时间戳,使每次请求url不一样,不然请求会被缓存)
!> 由于接口做了缓存处理 ( 缓存 2 分钟,不缓存数据极容易引起网易服务器高频ip错误 , 可在 app.js 设置 , 可能会导致登后获取不到 cookie), **相同的 url** 会在两分钟内只向网易服务器发一次请求 , 如果遇到不需要缓
!> 由于接口做了缓存处理 ( 缓存 2 分钟,不缓存数据极容易引起网易服务器高频ip错误 , 可在 app.js 设置 , 可能会导致登后获取不到 cookie), **相同的 url** 会在两分钟内只向网易服务器发一次请求 , 如果遇到不需要缓
存结果的接口 , 可在请求 url 后面加一个时间戳参数使 url 不同 , 例子 :
`/simi/playlist?id=347230&timestamp=1503019930000` (之所以加入缓存机制是因为项目早期没有缓存机制,很多 issues 都是报 IP高频,请按自己需求改造缓存中间件(app.js),源码不复杂)
!> 如果是跨域请求 , 请在所有请求带上 `xhrFields: { withCredentials: true }` (axios 为 `withCredentials: true`)否则
可能会因为没带上 cookie 导致 301, 具体例子可看 `public/test.html`, 访问`http://localhost:3000/test.html`(默认端口的话) 例子使用 jQuery 和 axios
!> 301 错误基本都是没登录就调用了需要登录的接口,如果登了还是提示 301, 基本都是缓存把数据缓存起来了,解决方法是加时间戳或者等待 2 分钟或者重启服务重新登录后再调用接口,可自行改造缓存方法
!> 301 错误基本都是没登录就调用了需要登录的接口,如果登了还是提示 301, 基本都是缓存把数据缓存起来了,解决方法是加时间戳或者等待 2 分钟或者重启服务重新登录后再调用接口,可自行改造缓存方法
!> 部分接口如登录接口不能调用太频繁 , 否则可能会触发 503 错误或者 ip 高频错误 ,若需频繁调用 , 需要准备 IP 代理池 (更新:已加入缓存机制,但仍需注意).
......@@ -358,7 +358,7 @@ $ sudo docker run -d -p 3000:3000 netease-music-api
**可选参数 :**
`countrycode`: 国家码,用于国外手机号登,例如美国传入:`1`
`countrycode`: 国家码,用于国外手机号登,例如美国传入:`1`
`md5_password`: md5加密后的密码,传入后 `password` 将失效
......@@ -503,7 +503,7 @@ v3.30.0后支持手动传入cookie,登录接口返回内容新增 `cookie` 字
### 获取用户详情
说明 : 登后调用此接口 , 传入用户 id, 可以获取用户详情
说明 : 登后调用此接口 , 传入用户 id, 可以获取用户详情
**必选参数 :** `uid` : 用户 id
......@@ -513,7 +513,7 @@ v3.30.0后支持手动传入cookie,登录接口返回内容新增 `cookie` 字
### 获取用户信息 , 歌单,收藏,mv, dj 数量
说明 : 登后调用此接口 , 可以获取用户信息
说明 : 登后调用此接口 , 可以获取用户信息
**接口地址 :** `/user/subcount`
......@@ -521,7 +521,7 @@ v3.30.0后支持手动传入cookie,登录接口返回内容新增 `cookie` 字
### 获取用户等级信息
说明 : 登陆后调用此接口 , 可以获取用户等级信息,包含当前登陆天数,听歌次数,下一等级需要的登录天数和听歌次数,当前等级进度,对应 https://music.163.com/#/user/level
说明 : 登录后调用此接口 , 可以获取用户等级信息,包含当前登录天数,听歌次数,下一等级需要的登录天数和听歌次数,当前等级进度,对应 https://music.163.com/#/user/level
**接口地址 :** `/user/level`
......@@ -529,7 +529,7 @@ v3.30.0后支持手动传入cookie,登录接口返回内容新增 `cookie` 字
### 更新用户信息
说明 : 登后调用此接口 , 传入相关信息,可以更新用户信息
说明 : 登后调用此接口 , 传入相关信息,可以更新用户信息
**必选参数 :**
......@@ -552,7 +552,7 @@ signature:用户签名
**调用例子 :** `/user/update?gender=0&signature=测试签名&city=440300&nickname=binary&birthday=1525918298004&province=440000`
### 更新头像
说明 : 登后调用此接口,使用`'Content-Type': 'multipart/form-data'`上传图片formData(name为'imgFile'),可更新头像(参考:https://github.com/Binaryify/NeteaseCloudMusicApi/blob/master/public/avatar_update.html)
说明 : 登后调用此接口,使用`'Content-Type': 'multipart/form-data'`上传图片formData(name为'imgFile'),可更新头像(参考:https://github.com/Binaryify/NeteaseCloudMusicApi/blob/master/public/avatar_update.html)
**可选参数 :**
......@@ -572,7 +572,7 @@ signature:用户签名
### 获取用户歌单
说明 : 登后调用此接口 , 传入用户 id, 可以获取用户歌单
说明 : 登后调用此接口 , 传入用户 id, 可以获取用户歌单
**必选参数 :** `uid` : 用户 id
......@@ -591,7 +591,7 @@ signature:用户签名
### 更新歌单
说明 : 登后调用此接口,可以更新用户歌单
说明 : 登后调用此接口,可以更新用户歌单
**必选参数 :**
......@@ -610,7 +610,7 @@ tags:歌单tag ,多个用 `;` 隔开,只能用官方规定标签
**调用例子 :** `/playlist/update?id=24381616&name=新歌单&desc=描述&tags=欧美`
### 更新歌单描述
说明 : 登后调用此接口,可以单独更新用户歌单描述
说明 : 登后调用此接口,可以单独更新用户歌单描述
**必选参数 :**
```
......@@ -624,7 +624,7 @@ desc:歌单描述
**调用例子 :** `/playlist/desc/update?id=24381616&desc=描述`
### 更新歌单名
说明 : 登后调用此接口,可以单独更新用户歌单名
说明 : 登后调用此接口,可以单独更新用户歌单名
**必选参数 :**
......@@ -639,7 +639,7 @@ name: 歌单名
**调用例子 :** `/playlist/name/update?id=24381616&name=歌单名`
### 更新歌单标签
说明 : 登后调用此接口,可以单独更新用户歌单标签
说明 : 登后调用此接口,可以单独更新用户歌单标签
**必选参数 :**
......@@ -655,7 +655,7 @@ tags: 歌单标签
### 歌单封面上传
说明 : 登后调用此接口,使用`'Content-Type': 'multipart/form-data'`上传图片formData(name为'imgFile'),可更新歌单封面(参考:https://github.com/Binaryify/NeteaseCloudMusicApi/blob/master/public/playlist_cover_update.html)
说明 : 登后调用此接口,使用`'Content-Type': 'multipart/form-data'`上传图片formData(name为'imgFile'),可更新歌单封面(参考:https://github.com/Binaryify/NeteaseCloudMusicApi/blob/master/public/playlist_cover_update.html)
**必选参数 :**
`id`: 歌单id 3143833470
......@@ -673,7 +673,7 @@ tags: 歌单标签
### 调整歌单顺序
说明 : 登后调用此接口,可以根据歌单id顺序调整歌单顺序
说明 : 登后调用此接口,可以根据歌单id顺序调整歌单顺序
**必选参数 :**
......@@ -685,7 +685,7 @@ tags: 歌单标签
**调用例子 :** `/playlist/order/update?ids=[111,222]`
### 调整歌曲顺序
说明 : 登后调用此接口,可以根据歌曲id顺序调整歌曲顺序
说明 : 登后调用此接口,可以根据歌曲id顺序调整歌曲顺序
**必选参数 :**
......@@ -699,7 +699,7 @@ tags: 歌单标签
### 获取用户电台
说明 : 登后调用此接口 , 传入用户 id, 可以获取用户电台
说明 : 登后调用此接口 , 传入用户 id, 可以获取用户电台
**必选参数 :** `uid` : 用户 id
......@@ -709,7 +709,7 @@ tags: 歌单标签
### 获取用户关注列表
说明 : 登后调用此接口 , 传入用户 id, 可以获取用户关注列表
说明 : 登后调用此接口 , 传入用户 id, 可以获取用户关注列表
**必选参数 :** `uid` : 用户 id
......@@ -725,7 +725,7 @@ tags: 歌单标签
### 获取用户粉丝列表
说明 : 登后调用此接口 , 传入用户 id, 可以获取用户粉丝列表
说明 : 登后调用此接口 , 传入用户 id, 可以获取用户粉丝列表
**必选参数 :** `uid` : 用户 id
......@@ -740,7 +740,7 @@ tags: 歌单标签
### 获取用户动态
说明 : 登后调用此接口 , 传入用户 id, 可以获取用户动态
说明 : 登后调用此接口 , 传入用户 id, 可以获取用户动态
**必选参数 :** `uid` : 用户 id
......@@ -765,7 +765,7 @@ tags: 歌单标签
```
### 转发用户动态
说明 : 登后调用此接口 ,可以转发用户动态
说明 : 登后调用此接口 ,可以转发用户动态
**必选参数 :** `uid` : 用户 id
......@@ -779,7 +779,7 @@ tags: 歌单标签
### 删除用户动态
说明 : 登后调用此接口 ,可以删除用户动态
说明 : 登后调用此接口 ,可以删除用户动态
**必选参数 :** `evId` : 动态 id
......@@ -788,7 +788,7 @@ tags: 歌单标签
**调用例子 :** `/event/del?evId=6712917601`
### 分享歌曲、歌单、mv、电台、电台节目到动态
说明 : 登后调用此接口 ,可以分享歌曲、歌单、mv、电台、电台节目到动态
说明 : 登后调用此接口 ,可以分享歌曲、歌单、mv、电台、电台节目到动态
**必选参数 :** `id` : 资源 id (歌曲,歌单,mv,电台,电台节目对应 id)
......@@ -802,7 +802,7 @@ tags: 歌单标签
### 获取动态评论
说明 : 登后调用此接口 , 可以获取动态下评论
说明 : 登后调用此接口 , 可以获取动态下评论
**必选参数 :** `threadId` : 动态 id,可通过 `/event``/user/event` 接口获取
......@@ -812,7 +812,7 @@ tags: 歌单标签
### 关注/取消关注用户
说明 : 登后调用此接口 , 传入用户 id, 和操作 t,可关注/取消关注用户
说明 : 登后调用此接口 , 传入用户 id, 和操作 t,可关注/取消关注用户
**必选参数 :**
......@@ -826,7 +826,7 @@ tags: 歌单标签
### 获取用户播放记录
说明 : 登后调用此接口 , 传入用户 id, 可获取用户播放记录
说明 : 登后调用此接口 , 传入用户 id, 可获取用户播放记录
**必选参数 :** `uid` : 用户 id
......@@ -1950,7 +1950,7 @@ mp3url 不能直接用 , 可通过 `/song/url` 接口传入歌曲 id 获取具
**调用例子 :** `/top/album?offset=0&limit=30&year=2019&month=6`
### 全部新碟
说明 : 登后调用此接口 ,可获取全部新碟
说明 : 登后调用此接口 ,可获取全部新碟
**可选参数 :**
......@@ -2294,7 +2294,7 @@ type : 地区
### 云盘
说明 : 登后调用此接口 , 可获取云盘数据 , 获取的数据没有对应 url, 需要再调用一
说明 : 登后调用此接口 , 可获取云盘数据 , 获取的数据没有对应 url, 需要再调用一
`/song/url` 获取 url
**可选参数 :**
......@@ -2308,7 +2308,7 @@ type : 地区
**调用例子 :** `/user/cloud`
### 云盘数据详情
说明 : 登后调用此接口 , 传入云盘歌曲 id,可获取云盘数据详情
说明 : 登后调用此接口 , 传入云盘歌曲 id,可获取云盘数据详情
**必选参数 :** `id`: 歌曲id,可多个,用逗号隔开
......@@ -2318,7 +2318,7 @@ type : 地区
### 云盘歌曲删除
说明 : 登后调用此接口 , 可删除云盘歌曲
说明 : 登后调用此接口 , 可删除云盘歌曲
**必选参数 :** `id`: 歌曲id,可多个,用逗号隔开
......@@ -2367,7 +2367,7 @@ type : 地区
### 电台 - 节目榜
说明 : 登后调用此接口 , 可获得电台节目榜
说明 : 登后调用此接口 , 可获得电台节目榜
**可选参数 :**
......@@ -2438,7 +2438,7 @@ type : 地区
### 电台 - 新晋电台榜/热门电台榜
说明 : 登后调用此接口 , 可获得新晋电台榜/热门电台榜
说明 : 登后调用此接口 , 可获得新晋电台榜/热门电台榜
**可选参数 :**
......@@ -2468,7 +2468,7 @@ type : 地区
### 电台 - 推荐
说明 : 登后调用此接口 , 可获得推荐电台
说明 : 登后调用此接口 , 可获得推荐电台
**接口地址 :** `/dj/recommend`
......@@ -2476,7 +2476,7 @@ type : 地区
### 电台 - 分类
说明 : 登后调用此接口 , 可获得电台类型
说明 : 登后调用此接口 , 可获得电台类型
**接口地址 :** `/dj/catelist`
......@@ -2484,7 +2484,7 @@ type : 地区
### 电台 - 分类推荐
说明 : 登后调用此接口 , 传入分类,可获得对应类型电台列表
说明 : 登后调用此接口 , 传入分类,可获得对应类型电台列表
**必选参数 :** `type`: 电台类型 , 数字 , 可通过`/dj/catelist`获取 , 对应关系为
id 对应 此接口的 type, name 对应类型
......@@ -2495,7 +2495,7 @@ id 对应 此接口的 type, name 对应类型
### 电台 - 订阅
说明 : 登后调用此接口 , 传入`rid`, 可订阅 dj,dj 的 `rid` 可通过搜索指定
说明 : 登后调用此接口 , 传入`rid`, 可订阅 dj,dj 的 `rid` 可通过搜索指定
type='1009' 获取其 id, 如`/search?keywords= 代码时间 &type=1009`
**必选参数 :** `rid`: 电台 的 id
......@@ -2507,7 +2507,7 @@ type='1009' 获取其 id, 如`/search?keywords= 代码时间 &type=1009`
### 电台的订阅列表
说明 : 登后调用此接口 , 可获取订阅的电台列表
说明 : 登后调用此接口 , 可获取订阅的电台列表
**接口地址 :** `/dj/sublist`
......@@ -2529,7 +2529,7 @@ type='1009' 获取其 id, 如`/search?keywords= 代码时间 &type=1009`
### 电台 - 非热门类型
说明 : 登后调用此接口, 可获得电台非热门类型
说明 : 登后调用此接口, 可获得电台非热门类型
**接口地址 :** `/dj/category/excludehot`
......@@ -2538,7 +2538,7 @@ type='1009' 获取其 id, 如`/search?keywords= 代码时间 &type=1009`
### 电台 - 推荐类型
说明 : 登后调用此接口, 可获得电台推荐类型
说明 : 登后调用此接口, 可获得电台推荐类型
**接口地址 :** `/dj/category/recommend`
......@@ -2547,7 +2547,7 @@ type='1009' 获取其 id, 如`/search?keywords= 代码时间 &type=1009`
### 电台 - 今日优选
说明 : 登后调用此接口, 可获得电台今日优选
说明 : 登后调用此接口, 可获得电台今日优选
**接口地址 :** `/dj/today/perfered`
......@@ -2556,7 +2556,7 @@ type='1009' 获取其 id, 如`/search?keywords= 代码时间 &type=1009`
### 电台 - 详情
说明 : 登后调用此接口 , 传入`rid`, 可获得对应电台的详情介绍
说明 : 登后调用此接口 , 传入`rid`, 可获得对应电台的详情介绍
**必选参数 :** `rid`: 电台 的 id
......@@ -2566,7 +2566,7 @@ type='1009' 获取其 id, 如`/search?keywords= 代码时间 &type=1009`
### 电台 - 节目
说明 : 登后调用此接口 , 传入`rid`, 可查看对应电台的电台节目以及对应的 id, 需要
说明 : 登后调用此接口 , 传入`rid`, 可查看对应电台的电台节目以及对应的 id, 需要
注意的是这个接口返回的 mp3Url 已经无效 , 都为 null, 但是通过调用 `/song/url`
个接口 , 传入节目 id 仍然能获取到节目音频 , 如 `/song/url?id=478446370` 获取代
码时间的一个节目的音频
......@@ -2596,7 +2596,7 @@ type='1009' 获取其 id, 如`/search?keywords= 代码时间 &type=1009`
### 通知 - 私信
说明 : 登后调用此接口 ,可获取私信
说明 : 登后调用此接口 ,可获取私信
**可选参数 :**
......@@ -2610,7 +2610,7 @@ type='1009' 获取其 id, 如`/search?keywords= 代码时间 &type=1009`
### 发送私信
说明 : 登后调用此接口 , 传入用户 id 和要发送的信息, 可以发送私信,返回内容为历史私信,包含带歌单的私信信息(注:不能发送私信给自己)
说明 : 登后调用此接口 , 传入用户 id 和要发送的信息, 可以发送私信,返回内容为历史私信,包含带歌单的私信信息(注:不能发送私信给自己)
**必选参数 :**
......@@ -2624,7 +2624,7 @@ type='1009' 获取其 id, 如`/search?keywords= 代码时间 &type=1009`
### 私信内容
说明 : 登后调用此接口 , 可获取私信内容
说明 : 登后调用此接口 , 可获取私信内容
**必选参数 :**
`uid` : 用户 id
......@@ -2642,7 +2642,7 @@ type='1009' 获取其 id, 如`/search?keywords= 代码时间 &type=1009`
### 发送私信(带歌单)
说明 : 登后调用此接口 , 传入用户 id 和要发送的信息和歌单 id, 可以发送带歌单的私信(注:不能发送重复的歌单)
说明 : 登后调用此接口 , 传入用户 id 和要发送的信息和歌单 id, 可以发送带歌单的私信(注:不能发送重复的歌单)
**必选参数 :**
......@@ -2657,7 +2657,7 @@ type='1009' 获取其 id, 如`/search?keywords= 代码时间 &type=1009`
### 通知 - 评论
说明 : 登后调用此接口 ,可获取评论
说明 : 登后调用此接口 ,可获取评论
**必选参数 :** `uid`: 用户 的 id,只能和登录账号的 id 一致
......@@ -2674,7 +2674,7 @@ type='1009' 获取其 id, 如`/search?keywords= 代码时间 &type=1009`
### 通知 - @我
说明 : 登后调用此接口 ,可获取@我数据
说明 : 登后调用此接口 ,可获取@我数据
**可选参数 :**
......@@ -2689,7 +2689,7 @@ type='1009' 获取其 id, 如`/search?keywords= 代码时间 &type=1009`
### 通知 - 通知
说明 : 登后调用此接口 ,可获取通知
说明 : 登后调用此接口 ,可获取通知
**可选参数 :**
......@@ -2703,7 +2703,7 @@ type='1009' 获取其 id, 如`/search?keywords= 代码时间 &type=1009`
**调用例子 :** `/msg/notices?limit=3`
### 设置
说明 : 登后调用此接口 ,可获取用户设置
说明 : 登后调用此接口 ,可获取用户设置
**接口地址 :** `/setting`
......@@ -2763,14 +2763,14 @@ type='1009' 获取其 id, 如`/search?keywords= 代码时间 &type=1009`
### 我的数字专辑
说明 : 登后调用此接口 ,可获取我的数字专辑
说明 : 登后调用此接口 ,可获取我的数字专辑
**接口地址 :** `/digitalAlbum/purchased`
**调用例子 :** `/digitalAlbum/purchased?limit=10`
### 购买数字专辑
说明 : 登后调用此接口 ,可获取购买数字专辑的地址,把地址生成二维码后,可扫描购买专辑
说明 : 登后调用此接口 ,可获取购买数字专辑的地址,把地址生成二维码后,可扫描购买专辑
**必选参数 :**
......@@ -2785,7 +2785,7 @@ type='1009' 获取其 id, 如`/search?keywords= 代码时间 &type=1009`
**调用例子 :** `/digitalAlbum/ordering?id=86286082&payment=3&quantity=1`
### batch批量请求接口
说明 : 登后调用此接口 ,传入接口和对应原始参数(原始参数非文档里写的参数,需参考源码),可批量请求接口
说明 : 登后调用此接口 ,传入接口和对应原始参数(原始参数非文档里写的参数,需参考源码),可批量请求接口
**接口地址 :** `/batch`
......
......@@ -176,7 +176,7 @@ $ sudo docker run -d -p 3000:3000 netease-music-api
!> 为使用方便,降低门槛,登录接口直接使用了 get 明文请求,请按实际需求对源码修改
!> 由于接口做了缓存处理 ( 缓存 2 分钟 , 可在 app.js 设置 , 可能会导致登后获取不
!> 由于接口做了缓存处理 ( 缓存 2 分钟 , 可在 app.js 设置 , 可能会导致登后获取不
到 cookie), 相同的 url 会在两分钟内只向网易服务器发一次请求 , 如果遇到不需要缓
存结果的接口 , 可在请求 url 后面加一个时间戳参数使 url 不同 , 例子 :
`/simi/playlist?id=347230&timestamp=1503019930000`
......@@ -184,7 +184,7 @@ $ sudo docker run -d -p 3000:3000 netease-music-api
!> 如果是跨域请求 , 请在所有请求带上 `xhrFields: { withCredentials: true }` 否则
可能会因为没带上 cookie 导致 301, 具体例子可看 `public/test.html`, 例子使用 jQuery, axios 版本也类似
!> 301 错误基本都是没登录就调用了需要登录的接口,如果登了还是提示 301, 基本都是缓存把数据缓存起来了,解决方法是等待 2 分钟或者重启服务重新登录后再调用接口
!> 301 错误基本都是没登录就调用了需要登录的接口,如果登了还是提示 301, 基本都是缓存把数据缓存起来了,解决方法是等待 2 分钟或者重启服务重新登录后再调用接口
!> 部分接口如登录接口不能调用太频繁 , 否则可能会触发 503 错误或者 ip 高频错误 ,若需频繁调用 , 需要准备 IP 代理池 (更新:已加入缓存机制,但仍需注意).
......@@ -250,7 +250,7 @@ Cookies
### 获取用户详情
说明 : 登后调用此接口 , 传入用户 id, 可以获取用户详情
说明 : 登后调用此接口 , 传入用户 id, 可以获取用户详情
**必选参数 :** `uid` : 用户 id
......@@ -260,7 +260,7 @@ Cookies
### 获取用户信息 , 歌单,收藏,mv, dj 数量
说明 : 登后调用此接口 , 可以获取用户信息
说明 : 登后调用此接口 , 可以获取用户信息
**接口地址 :** `/user/subcount`
......@@ -268,7 +268,7 @@ Cookies
### 更新用户信息
说明 : 登后调用此接口 , 传入相关信息,可以更新用户信息
说明 : 登后调用此接口 , 传入相关信息,可以更新用户信息
**必选参数 :**
......@@ -287,7 +287,7 @@ signature:用户签名
### 获取用户歌单
说明 : 登后调用此接口 , 传入用户 id, 可以获取用户歌单
说明 : 登后调用此接口 , 传入用户 id, 可以获取用户歌单
**必选参数 :** `uid` : 用户 id
......@@ -300,7 +300,7 @@ signature:用户签名
### 更新歌单
说明 : 登后调用此接口,可以更新用户歌单
说明 : 登后调用此接口,可以更新用户歌单
参数:
```
......@@ -316,7 +316,7 @@ tags:歌单tag
### 发送私信
说明 : 登后调用此接口 , 传入用户 id 和要发送的信息, 可以发送私信,返回内容为历史私信,包含带歌单的私信信息(注:不能发送私信给自己)
说明 : 登后调用此接口 , 传入用户 id 和要发送的信息, 可以发送私信,返回内容为历史私信,包含带歌单的私信信息(注:不能发送私信给自己)
**必选参数 :**
......@@ -332,7 +332,7 @@ tags:歌单tag
### 发送私信(带歌单)
说明 : 登后调用此接口 , 传入用户 id 和要发送的信息和歌单 id, 可以发送带歌单的私信(注:不能发送重复的歌单)
说明 : 登后调用此接口 , 传入用户 id 和要发送的信息和歌单 id, 可以发送带歌单的私信(注:不能发送重复的歌单)
**必选参数 :**
......@@ -348,7 +348,7 @@ tags:歌单tag
### 获取用户电台
说明 : 登后调用此接口 , 传入用户 id, 可以获取用户电台
说明 : 登后调用此接口 , 传入用户 id, 可以获取用户电台
**必选参数 :** `uid` : 用户 id
......@@ -358,7 +358,7 @@ tags:歌单tag
### 获取用户关注列表
说明 : 登后调用此接口 , 传入用户 id, 可以获取用户关注列表
说明 : 登后调用此接口 , 传入用户 id, 可以获取用户关注列表
**必选参数 :** `uid` : 用户 id
......@@ -374,7 +374,7 @@ tags:歌单tag
### 获取用户粉丝列表
说明 : 登后调用此接口 , 传入用户 id, 可以获取用户粉丝列表
说明 : 登后调用此接口 , 传入用户 id, 可以获取用户粉丝列表
**必选参数 :** `uid` : 用户 id
......@@ -387,7 +387,7 @@ tags:歌单tag
### 获取用户动态
说明 : 登后调用此接口 , 传入用户 id, 可以获取用户动态
说明 : 登后调用此接口 , 传入用户 id, 可以获取用户动态
**必选参数 :** `uid` : 用户 id
......@@ -397,7 +397,7 @@ tags:歌单tag
### 获取用户播放记录
说明 : 登后调用此接口 , 传入用户 id, 可获取用户播放记录
说明 : 登后调用此接口 , 传入用户 id, 可获取用户播放记录
**必选参数 :** `uid` : 用户 id
......@@ -1323,7 +1323,7 @@ MV 数据 , 数据包含 mv 名字 , 歌手 , 发布时间 , mv 视频地址等
### 云盘
说明 : 登后调用此接口 , 可获取云盘数据 , 获取的数据没有对应 url, 需要再调用一
说明 : 登后调用此接口 , 可获取云盘数据 , 获取的数据没有对应 url, 需要再调用一
`/music/url` 获取 url
**接口地址 :** `/user/cloud`
......@@ -1332,7 +1332,7 @@ MV 数据 , 数据包含 mv 名字 , 歌手 , 发布时间 , mv 视频地址等
### 电台 - 推荐
说明 : 登后调用此接口 , 可获得推荐电台
说明 : 登后调用此接口 , 可获得推荐电台
**接口地址 :** `/dj/recommend`
......@@ -1340,7 +1340,7 @@ MV 数据 , 数据包含 mv 名字 , 歌手 , 发布时间 , mv 视频地址等
### 电台 - 分类
说明 : 登后调用此接口 , 可获得电台类型
说明 : 登后调用此接口 , 可获得电台类型
**接口地址 :** `/dj/catelist`
......@@ -1348,7 +1348,7 @@ MV 数据 , 数据包含 mv 名字 , 歌手 , 发布时间 , mv 视频地址等
### 电台 - 分类推荐
说明 : 登后调用此接口 , 可获得推荐电台
说明 : 登后调用此接口 , 可获得推荐电台
**必选参数 :** `type`: 电台类型 , 数字 , 可通过`/dj/catelist`获取 , 对应关系为
id 对应 此接口的 type, name 对应类型意义
......@@ -1359,7 +1359,7 @@ id 对应 此接口的 type, name 对应类型意义
### 电台 - 订阅
说明 : 登后调用此接口 , 传入`rid`, 可订阅 dj,dj 的 `rid` 可通过搜索指定
说明 : 登后调用此接口 , 传入`rid`, 可订阅 dj,dj 的 `rid` 可通过搜索指定
type='1009' 获取其 id, 如`/search?keywords= 代码时间 &type=1009`
**必选参数 :** `rid`: 电台 的 id
......@@ -1371,7 +1371,7 @@ type='1009' 获取其 id, 如`/search?keywords= 代码时间 &type=1009`
### 电台的订阅列表
说明 : 登后调用此接口 , 可获取订阅的电台列表
说明 : 登后调用此接口 , 可获取订阅的电台列表
**接口地址 :** `/dj/sublist`
......@@ -1387,7 +1387,7 @@ type='1009' 获取其 id, 如`/search?keywords= 代码时间 &type=1009`
### 电台 - 详情
说明 : 登后调用此接口 , 传入`rid`, 可获得对应电台的详情介绍
说明 : 登后调用此接口 , 传入`rid`, 可获得对应电台的详情介绍
**必选参数 :** `rid`: 电台 的 id
......@@ -1397,7 +1397,7 @@ type='1009' 获取其 id, 如`/search?keywords= 代码时间 &type=1009`
### 电台 - 节目
说明 : 登后调用此接口 , 传入`rid`, 可查看对应电台的电台节目以及对应的 id, 需要
说明 : 登后调用此接口 , 传入`rid`, 可查看对应电台的电台节目以及对应的 id, 需要
注意的是这个接口返回的 mp3Url 已经无效 , 都为 null, 但是通过调用 `/music/url`
个接口 , 传入节目 id 仍然能获取到节目音频 , 如 `/music/url?id=478446370` 获取代
码时间的一个节目的音频
......
......@@ -34,7 +34,7 @@ declare module 'NeteaseCloudMusicApi' {
export const enum SubAction {
sub = 1,
ubsub = 0,
unsub = 0,
}
export function activate_init_profile(
......
此差异已折叠。
......@@ -44,8 +44,7 @@
"axios": "^0.20.0",
"express": "^4.17.1",
"express-fileupload": "^1.1.9",
"pac-proxy-agent": "^4.0.0",
"request": "^2.88.0"
"pac-proxy-agent": "^4.0.0"
},
"devDependencies": {
"@types/node": "14.11.2",
......@@ -61,6 +60,6 @@
"mocha": "8.1.3",
"power-assert": "1.6.1",
"prettier": "2.1.2",
"typescript": "4.0.2"
"typescript": "4.0.3"
}
}
const assert = require('assert')
const request = require('request')
const axios = require('axios')
const host = global.host || 'http://localhost:3000'
describe('测试获取歌手专辑列表是否正常', () => {
......@@ -8,14 +8,18 @@ describe('测试获取歌手专辑列表是否正常', () => {
id: 32311,
}
request.get({ url: `${host}/album`, qs: qs }, (err, res, body) => {
if (!err && res.statusCode == 200) {
body = JSON.parse(body)
assert(body.code === 200)
axios
.get(`${host}/album`, {
params: qs,
})
.then(({ status, data }) => {
if (status == 200) {
assert(data.code === 200)
}
done()
} else {
})
.catch((err) => {
done(err)
}
})
})
})
})
const assert = require('assert')
const request = require('request')
const axios = require('axios')
const host = global.host || 'http://localhost:3000'
describe('测试获取评论是否正常', () => {
......@@ -8,14 +8,18 @@ describe('测试获取评论是否正常', () => {
id: 32311,
}
request.get({ url: `${host}/comment/album`, qs: qs }, (err, res, body) => {
if (!err && res.statusCode == 200) {
body = JSON.parse(body)
assert(body.code === 200)
axios
.get(`${host}/comment/album`, {
params: qs,
})
.then(({ status, data }) => {
if (status == 200) {
assert(data.code === 200)
}
done()
} else {
})
.catch((err) => {
done(err)
}
})
})
})
})
const assert = require('assert')
const request = require('request')
const axios = require('axios')
const host = global.host || 'http://localhost:3000'
console.log('注意: 测试登录需在 test/login.test.js 中填写账号密码!!!')
......@@ -12,18 +12,21 @@ describe('测试登录是否正常', () => {
password: process.env.NCM_API_TEST_LOGIN_PASSWORD || password || '',
}
request.get(
{ url: `${host}/login/cellphone`, qs: qs },
(err, res, body) => {
if (!err && res.statusCode == 200) {
body = JSON.parse(body)
assert(body.code === 200)
console.log('昵称:' + body.profile.nickname)
axios
.get(`${host}/login/cellphone`, {
params: qs,
})
.then(({ status, data }) => {
if (status == 200) {
console.log('昵称:' + data.profile.nickname)
assert(data.code === 200)
done()
} else {
done('登录错误')
}
},
)
})
.catch((err) => {
done(err)
})
})
})
const assert = require('assert')
const request = require('request')
const axios = require('axios')
const host = global.host || 'http://localhost:3000'
describe('测试获取歌词是否正常', () => {
......@@ -8,14 +8,18 @@ describe('测试获取歌词是否正常', () => {
id: 347230,
}
request.get({ url: `${host}/lyric`, qs: qs }, (err, res, body) => {
if (!err && res.statusCode == 200) {
body = JSON.parse(body)
assert(typeof body.lrc !== 'undefined')
axios
.get(`${host}/lyric`, {
params: qs,
})
.then(({ status, data }) => {
if (status == 200) {
assert(typeof data.lrc !== 'undefined')
}
done()
} else {
})
.catch((err) => {
done(err)
}
})
})
})
})
const assert = require('assert')
const request = require('request')
const axios = require('axios')
const host = global.host || 'http://localhost:3000'
describe('测试获取歌曲是否正常', () => {
......@@ -9,14 +9,18 @@ describe('测试获取歌曲是否正常', () => {
br: 999000,
}
request.get({ url: `${host}/song/url`, qs: qs }, (err, res, body) => {
if (!err && res.statusCode == 200) {
body = JSON.parse(body)
assert(!!body.data[0].url)
axios
.get(`${host}/song/url`, {
params: qs,
})
.then(({ status, data }) => {
if (status == 200) {
assert(!!data.data[0].url)
}
done()
} else {
})
.catch((err) => {
done(err)
}
})
})
})
})
const assert = require('assert')
const request = require('request')
const axios = require('axios')
const host = global.host || 'http://localhost:3000'
describe('测试搜索是否正常', () => {
......@@ -8,14 +8,18 @@ describe('测试搜索是否正常', () => {
keywords: '海阔天空',
type: 1,
}
request.get({ url: `${host}/search`, qs: qs }, (err, res, body) => {
if (!err && res.statusCode == 200) {
body = JSON.parse(body)
assert(body.result.songs[0].name === '海阔天空')
axios
.get(`${host}/search`, {
params: qs,
})
.then(({ status, data }) => {
if (status == 200) {
assert(data.result.songs[0].name === '海阔天空')
}
done()
} else {
})
.catch((err) => {
done(err)
}
})
})
})
})
const encrypt = require('./crypto')
const request = require('request')
const axios = require('axios')
const queryString = require('querystring')
const PacProxyAgent = require('pac-proxy-agent')
const zlib = require('zlib')
const http = require('http')
const https = require('https')
// request.debug = true // 开启可看到更详细信息
......@@ -114,66 +115,47 @@ const createRequest = (method, url, data, options) => {
method: method,
url: url,
headers: headers,
body: queryString.stringify(data),
data: queryString.stringify(data),
httpAgent: new http.Agent({ keepAlive: true }),
httpsAgent: new https.Agent({ keepAlive: true }),
}
if (options.crypto === 'eapi') settings.encoding = null
if (/\.pac$/i.test(options.proxy)) {
settings.agent = new PacProxyAgent(options.proxy)
settings.httpAgent = new PacProxyAgent(options.proxy)
settings.httpsAgent = new PacProxyAgent(options.proxy)
} else {
settings.proxy = options.proxy
}
request(settings, (err, res, body) => {
if (err) {
answer.status = 502
answer.body = { code: 502, msg: err.stack }
reject(answer)
} else {
axios(settings)
.then((res) => {
const body = res.data
answer.cookie = (res.headers['set-cookie'] || []).map((x) =>
x.replace(/\s*Domain=[^(;|$)]+;*/, ''),
)
try {
if (options.crypto === 'eapi') {
zlib.unzip(body, function (err, buffer) {
const _buffer = err ? body : buffer
try {
try {
answer.body = JSON.parse(encrypt.decrypt(_buffer).toString())
answer.status = answer.body.code || res.statusCode
} catch (e) {
answer.body = JSON.parse(_buffer.toString())
answer.status = res.statusCode
}
} catch (e) {
answer.body = _buffer.toString()
answer.status = res.statusCode
}
answer.status =
100 < answer.status && answer.status < 600 ? answer.status : 400
if (answer.status === 200) resolve(answer)
else reject(answer)
})
return false
} else {
answer.body = JSON.parse(body)
answer.status = answer.body.code || res.statusCode
if (answer.body.code === 502) {
answer.status = 200
}
answer.body = body
answer.status = answer.body.code || res.status
if (answer.body.code === 502) {
answer.status = 200
}
} catch (e) {
answer.body = body
answer.status = res.statusCode
answer.status = res.status
}
answer.status =
100 < answer.status && answer.status < 600 ? answer.status : 400
if (answer.status == 200) resolve(answer)
else reject(answer)
}
})
})
.catch((err) => {
answer.status = 502
answer.body = { code: 502, msg: err }
reject(answer)
})
})
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册