mirror of
https://gitlab.com/Binaryify/neteasecloudmusicapi.git
synced 2025-05-23 22:37:41 +08:00
This commit is contained in:
parent
aea538c8ee
commit
8bb37684f8
10
CHANGELOG.MD
10
CHANGELOG.MD
@ -1,6 +1,14 @@
|
||||
# 更新日志
|
||||
|
||||
### 3.0.2 | 2018.10.31
|
||||
### 3.0.3 | 2018.11.09
|
||||
- 修复取消喜欢歌曲失败问题 [#360](https://github.com/Binaryify/NeteaseCloudMusicApi/issues/360)
|
||||
|
||||
- 补充已喜欢音乐列表接口说明文档 [#370](https://github.com/Binaryify/NeteaseCloudMusicApi/issues/370)
|
||||
|
||||
- 默认关闭 debug 模式 [#365](https://github.com/Binaryify/NeteaseCloudMusicApi/pull/365)
|
||||
|
||||
- 更新 Dockerfile 文件 [#367](https://github.com/Binaryify/NeteaseCloudMusicApi/pull/367)
|
||||
|
||||
|
||||
### 3.0.1 | 2018.10.21
|
||||
|
||||
|
@ -99,6 +99,14 @@
|
||||
77. 热门评论
|
||||
78. 视频评论
|
||||
79. 退出登录
|
||||
80. 所有榜单内容摘要
|
||||
81. 收藏视频
|
||||
82. 收藏 MV
|
||||
83. 视频详情
|
||||
84. 相关视频
|
||||
85. 关注用户
|
||||
86. 新歌速递
|
||||
87. 喜欢音乐列表(无序)
|
||||
|
||||
## 环境要求
|
||||
|
||||
|
309
docs/README.md
309
docs/README.md
@ -102,30 +102,46 @@
|
||||
84. 相关视频
|
||||
85. 关注用户
|
||||
86. 新歌速递
|
||||
87. 喜欢音乐列表(无序)
|
||||
|
||||
## 安装
|
||||
|
||||
```shell
|
||||
$ git clone git@github.com:Binaryify/NeteaseCloudMusicApi.git
|
||||
|
||||
|
||||
|
||||
$ npm install
|
||||
|
||||
|
||||
|
||||
```
|
||||
|
||||
## 运行
|
||||
|
||||
```shell
|
||||
$ node app.js
|
||||
|
||||
|
||||
|
||||
```
|
||||
|
||||
服务器启动默认端口为 3000, 若不想使用 3000 端口 , 可使用以下命令 : Mac/Linux
|
||||
|
||||
```shell
|
||||
$ PORT=4000 node app.js
|
||||
|
||||
|
||||
|
||||
```
|
||||
|
||||
windows 下使用 git-bash 或者 cmder 等终端执行以下命令 :
|
||||
|
||||
```shell
|
||||
$ set PORT=4000 && node app.js
|
||||
|
||||
|
||||
|
||||
```
|
||||
|
||||
## 可以使用代理
|
||||
@ -162,18 +178,42 @@ request 相关的环境变量
|
||||
|
||||
```shell
|
||||
docker pull twesix/netease-cloud-music
|
||||
|
||||
|
||||
|
||||
docker run -d -p 3000:3000 --name netease-cloud-music twesix/netease-music-api
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// 去掉或者设置相关的环境变量
|
||||
|
||||
|
||||
|
||||
docker run -d -p 3000:3000 --name netease-cloud-music -e http_proxy= -e https_proxy= -e no_proxy= -e HTTP_PROXY= -e HTTPS_PROXY= -e NO_PROXY= netease-cloud-music
|
||||
|
||||
|
||||
|
||||
```
|
||||
|
||||
> 由于 docker 镜像更新不是很及时,推荐自己 build, 以下为 build 镜像的方式
|
||||
|
||||
```
|
||||
$ git clone https://github.com/Binaryify/NeteaseCloudMusicApi && cd NeteaseCloudMusicApi
|
||||
|
||||
|
||||
|
||||
$ sudo docker build . -t netease-music-api
|
||||
|
||||
|
||||
|
||||
$ sudo docker run -d -p 3000:3000 netease-music-api
|
||||
|
||||
|
||||
|
||||
```
|
||||
|
||||
## 接口文档
|
||||
@ -182,7 +222,7 @@ $ sudo docker run -d -p 3000:3000 netease-music-api
|
||||
|
||||
!> 为使用方便,降低门槛,登录接口直接使用了 get 明文请求,请按实际需求对源码修改
|
||||
|
||||
!> 由于接口做了缓存处理 ( 缓存 2 分钟 , 可在 app.js 设置 , 可能会导致登陆后获取不
|
||||
!> 由于接口做了缓存处理 ( 缓存 2 分钟,不缓存数据极容易引起网易服务器高频ip错误 , 可在 app.js 设置 , 可能会导致登陆后获取不
|
||||
到 cookie), 相同的 url 会在两分钟内只向网易服务器发一次请求 , 如果遇到不需要缓
|
||||
存结果的接口 , 可在请求 url 后面加一个时间戳参数使 url 不同 , 例子 :
|
||||
`/simi/playlist?id=347230×tamp=1503019930000`
|
||||
@ -280,11 +320,29 @@ Cookies
|
||||
|
||||
```
|
||||
gender: 性别 0:保密 1:男性 2:女性
|
||||
|
||||
|
||||
|
||||
birthday: 出生日期,时间戳 unix timestamp
|
||||
|
||||
|
||||
|
||||
nickname: 用户昵称
|
||||
|
||||
|
||||
|
||||
province: 省份id
|
||||
|
||||
|
||||
|
||||
city: 城市id
|
||||
|
||||
|
||||
|
||||
signature:用户签名
|
||||
|
||||
|
||||
|
||||
```
|
||||
|
||||
**接口地址 :** `/user/subcount`
|
||||
@ -311,9 +369,21 @@ signature:用户签名
|
||||
|
||||
```
|
||||
id:歌单id
|
||||
|
||||
|
||||
|
||||
name:歌单名字
|
||||
|
||||
|
||||
|
||||
desc:歌单描述
|
||||
|
||||
|
||||
|
||||
tags:歌单tag
|
||||
|
||||
|
||||
|
||||
```
|
||||
|
||||
**接口地址 :** `/playlist/update`
|
||||
@ -369,6 +439,7 @@ tags:歌单tag
|
||||
**必选参数 :** `uid` : 用户 id
|
||||
|
||||
**可选参数 :**
|
||||
|
||||
`limit` : 返回数量 , 默认为 30
|
||||
|
||||
`offset` : 偏移数量,用于分页 , 如
|
||||
@ -443,6 +514,7 @@ tags:歌单tag
|
||||
说明 : 调用此接口,可获取歌手分类列表
|
||||
**必选参数 :** `cat` : 即 category Code,歌手类型,默认 1001,返回华语男歌手数据
|
||||
**可选参数 :**
|
||||
|
||||
`limit` : 返回数量 , 默认为 30
|
||||
|
||||
`offset` : 偏移数量,用于分页 , 如
|
||||
@ -453,21 +525,69 @@ category Code 取值:
|
||||
|
||||
```
|
||||
入驻歌手 5001
|
||||
|
||||
|
||||
|
||||
华语男歌手 1001
|
||||
|
||||
|
||||
|
||||
华语女歌手 1002
|
||||
|
||||
|
||||
|
||||
华语组合/乐队 1003
|
||||
|
||||
|
||||
|
||||
欧美男歌手 2001
|
||||
|
||||
|
||||
|
||||
欧美女歌手 2002
|
||||
|
||||
|
||||
|
||||
欧美组合/乐队 2003
|
||||
|
||||
|
||||
|
||||
日本男歌手 6001
|
||||
|
||||
|
||||
|
||||
日本女歌手 6002
|
||||
|
||||
|
||||
|
||||
日本组合/乐队 6003
|
||||
|
||||
|
||||
|
||||
韩国男歌手 7001
|
||||
|
||||
|
||||
|
||||
韩国女歌手 7002
|
||||
|
||||
|
||||
|
||||
韩国组合/乐队 7003
|
||||
|
||||
|
||||
|
||||
其他男歌手 4001
|
||||
|
||||
|
||||
|
||||
其他女歌手 4002
|
||||
|
||||
|
||||
|
||||
其他组合/乐队 4003
|
||||
|
||||
|
||||
|
||||
```
|
||||
|
||||
**接口地址 :** `/artist/list`
|
||||
@ -560,7 +680,9 @@ category Code 取值:
|
||||
返回数据如下图 :
|
||||
|
||||

|
||||
|
||||

|
||||
|
||||

|
||||
|
||||
### 获取精品歌单
|
||||
@ -673,6 +795,7 @@ mp3url 不能直接用 , 可通过 `/song/url` 接口传入歌曲 id 获取具
|
||||
**必选参数 :** `keywords` : 关键词
|
||||
|
||||
**可选参数 :**
|
||||
|
||||
`limit` : 返回数量 , 默认为 30
|
||||
|
||||
`offset` : 偏移数量,用于分页 , 如
|
||||
@ -713,6 +836,7 @@ mp3url 不能直接用 , 可通过 `/song/url` 接口传入歌曲 id 获取具
|
||||
说明 : 调用此接口 , 传入类型和歌单 id 可收藏歌单或者取消收藏歌单
|
||||
|
||||
**必选参数 :**
|
||||
|
||||
`t` : 类型,1:收藏,2:取消收藏
|
||||
`id` : 歌单 id
|
||||
|
||||
@ -728,6 +852,7 @@ mp3url 不能直接用 , 可通过 `/song/url` 接口传入歌曲 id 获取具
|
||||
说明 : 调用此接口 , 可以添加歌曲到歌单或者从歌单删除某首歌曲 ( 需要登录 )
|
||||
|
||||
**必选参数 :**
|
||||
|
||||
`op`: 从歌单增加单曲为 add, 删除为 del
|
||||
|
||||
`pid`: 歌单 id
|
||||
@ -760,10 +885,25 @@ mp3url 不能直接用 , 可通过 `/song/url` 接口传入歌曲 id 获取具
|
||||
|
||||
```
|
||||
全部:0
|
||||
|
||||
|
||||
|
||||
华语:7
|
||||
|
||||
|
||||
|
||||
欧美:96
|
||||
|
||||
|
||||
|
||||
日本:8
|
||||
|
||||
|
||||
|
||||
韩国:16
|
||||
|
||||
|
||||
|
||||
```
|
||||
|
||||
`limit`: 取出数量 , 默认为 100
|
||||
@ -879,11 +1019,29 @@ mp3url 不能直接用 , 可通过 `/song/url` 接口传入歌曲 id 获取具
|
||||
|
||||
```
|
||||
0: 歌曲
|
||||
|
||||
|
||||
|
||||
1: mv
|
||||
|
||||
|
||||
|
||||
2: 歌单
|
||||
|
||||
|
||||
|
||||
3: 专辑
|
||||
|
||||
|
||||
|
||||
4: 电台
|
||||
|
||||
|
||||
|
||||
5: 视频
|
||||
|
||||
|
||||
|
||||
```
|
||||
|
||||
**接口地址 :** `/comment/hot`
|
||||
@ -905,11 +1063,29 @@ mp3url 不能直接用 , 可通过 `/song/url` 接口传入歌曲 id 获取具
|
||||
|
||||
```
|
||||
0: 歌曲
|
||||
|
||||
|
||||
|
||||
1: mv
|
||||
|
||||
|
||||
|
||||
2: 歌单
|
||||
|
||||
|
||||
|
||||
3: 专辑
|
||||
|
||||
|
||||
|
||||
4: 电台
|
||||
|
||||
|
||||
|
||||
5: 视频
|
||||
|
||||
|
||||
|
||||
```
|
||||
|
||||
**接口地址 :** `comment/like`
|
||||
@ -925,17 +1101,36 @@ mp3url 不能直接用 , 可通过 `/song/url` 接口传入歌曲 id 获取具
|
||||
1. 发送评论
|
||||
|
||||
**必选参数**
|
||||
|
||||
`t`:1 发送
|
||||
|
||||
`tpye`: 数字,资源类型,对应歌曲,mv,专辑,歌单,电台,视频对应以下类型
|
||||
|
||||
```
|
||||
0: 歌曲
|
||||
|
||||
|
||||
|
||||
1: mv
|
||||
|
||||
|
||||
|
||||
2: 歌单
|
||||
|
||||
|
||||
|
||||
3: 专辑
|
||||
|
||||
|
||||
|
||||
4: 电台
|
||||
|
||||
|
||||
|
||||
5: 视频
|
||||
|
||||
|
||||
|
||||
```
|
||||
|
||||
`id`:对应资源 id
|
||||
@ -947,17 +1142,36 @@ mp3url 不能直接用 , 可通过 `/song/url` 接口传入歌曲 id 获取具
|
||||
2. 删除评论
|
||||
|
||||
**必选参数**
|
||||
|
||||
`t`:0 删除
|
||||
|
||||
`tpye`: 数字,资源类型,对应歌曲,mv,专辑,歌单,电台,视频对应以下类型
|
||||
|
||||
```
|
||||
0: 歌曲
|
||||
|
||||
|
||||
|
||||
1: mv
|
||||
|
||||
|
||||
|
||||
2: 歌单
|
||||
|
||||
|
||||
|
||||
3: 专辑
|
||||
|
||||
|
||||
|
||||
4: 电台
|
||||
|
||||
|
||||
|
||||
5: 视频
|
||||
|
||||
|
||||
|
||||
```
|
||||
|
||||
`id`:对应资源 id
|
||||
@ -983,8 +1197,17 @@ mp3url 不能直接用 , 可通过 `/song/url` 接口传入歌曲 id 获取具
|
||||
|
||||
```
|
||||
1: mv
|
||||
|
||||
|
||||
|
||||
4: 电台
|
||||
|
||||
|
||||
|
||||
5: 视频
|
||||
|
||||
|
||||
|
||||
```
|
||||
|
||||
`t`: 操作,1 为点赞,其他未取消点赞
|
||||
@ -1195,6 +1418,16 @@ mp3url 不能直接用 , 可通过 `/song/url` 接口传入歌曲 id 获取具
|
||||
|
||||

|
||||
|
||||
### 喜欢音乐列表
|
||||
|
||||
说明 : 调用此接口 , 传入用户 id, 可获取已喜欢音乐id列表(id数组)
|
||||
|
||||
**必选参数 :** `uid`: 用户 id
|
||||
|
||||
**接口地址 :** `/likelist`
|
||||
|
||||
**调用例子 :** `/likelist?uid=32953014`
|
||||
|
||||
### 垃圾桶
|
||||
|
||||
说明 : 调用此接口 , 传入音乐 id, 可把该音乐从私人 FM 中移除至垃圾桶
|
||||
@ -1340,6 +1573,7 @@ MV 数据 , 数据包含 mv 名字 , 歌手 , 发布时间 , mv 视频地址等
|
||||
**接口地址 :** `/mv/url`
|
||||
|
||||
**调用例子 :**
|
||||
|
||||
`/mv/url?id=5436712`
|
||||
|
||||
### 相关视频
|
||||
@ -1385,29 +1619,101 @@ MV 数据 , 数据包含 mv 名字 , 歌手 , 发布时间 , mv 视频地址等
|
||||
|
||||
```
|
||||
"0": 云音乐新歌榜,
|
||||
|
||||
|
||||
|
||||
"1": 云音乐热歌榜,
|
||||
|
||||
|
||||
|
||||
"2": 网易原创歌曲榜,
|
||||
|
||||
|
||||
|
||||
"3": 云音乐飙升榜,
|
||||
|
||||
|
||||
|
||||
"4": 云音乐电音榜,
|
||||
|
||||
|
||||
|
||||
"5": UK排行榜周榜,
|
||||
|
||||
|
||||
|
||||
"6": 美国Billboard周榜
|
||||
|
||||
|
||||
|
||||
"7": KTV嗨榜,
|
||||
|
||||
|
||||
|
||||
"8": iTunes榜,
|
||||
|
||||
|
||||
|
||||
"9": Hit FM Top榜,
|
||||
|
||||
|
||||
|
||||
"10": 日本Oricon周榜
|
||||
|
||||
|
||||
|
||||
"11": 韩国Melon排行榜周榜,
|
||||
|
||||
|
||||
|
||||
"12": 韩国Mnet排行榜周榜,
|
||||
|
||||
|
||||
|
||||
"13": 韩国Melon原声周榜,
|
||||
|
||||
|
||||
|
||||
"14": 中国TOP排行榜(港台榜),
|
||||
|
||||
|
||||
|
||||
"15": 中国TOP排行榜(内地榜)
|
||||
|
||||
|
||||
|
||||
"16": 香港电台中文歌曲龙虎榜,
|
||||
|
||||
|
||||
|
||||
"17": 华语金曲榜,
|
||||
|
||||
|
||||
|
||||
"18": 中国嘻哈榜,
|
||||
|
||||
|
||||
|
||||
"19": 法国 NRJ EuroHot 30周榜,
|
||||
|
||||
|
||||
|
||||
"20": 台湾Hito排行榜,
|
||||
|
||||
|
||||
|
||||
"21": Beatport全球电子舞曲榜,
|
||||
|
||||
|
||||
|
||||
"22": 云音乐ACG音乐榜,
|
||||
|
||||
|
||||
|
||||
"23": 云音乐嘻哈榜
|
||||
|
||||
|
||||
|
||||
```
|
||||
|
||||
**接口地址 :** `/top/list`
|
||||
@ -1517,6 +1823,7 @@ type='1009' 获取其 id, 如`/search?keywords= 代码时间 &type=1009`
|
||||
**必选参数 :** `rid`: 电台 的 id
|
||||
|
||||
**可选参数 :**
|
||||
|
||||
`limit` : 返回数量 , 默认为 30
|
||||
|
||||
`offset` : 偏移数量,用于分页 , 如
|
||||
|
@ -1,13 +1,18 @@
|
||||
// 红心与取消红心歌曲
|
||||
const { toBoolean } = require('../util')
|
||||
|
||||
module.exports = (query, request) => {
|
||||
query.like = (query.like ? true : false)
|
||||
const data = {
|
||||
trackId: query.id,
|
||||
like: query.like
|
||||
}
|
||||
return request(
|
||||
'POST', `http://music.163.com/weapi/radio/like?alg=${query.alg || 'itembased'}&trackId=${query.id}&like=${query.like}&time=${query.time || 25}`, data,
|
||||
{crypto: 'weapi', cookie: query.cookie, proxy: query.proxy}
|
||||
)
|
||||
}
|
||||
query.like = query.like ? true : false
|
||||
const data = {
|
||||
trackId: query.id,
|
||||
like: query.like
|
||||
}
|
||||
return request(
|
||||
'POST',
|
||||
`http://music.163.com/weapi/radio/like?alg=${query.alg ||
|
||||
'itembased'}&trackId=${query.id}&like=${query.like}&time=${query.time ||
|
||||
25}`,
|
||||
data,
|
||||
{ crypto: 'weapi', cookie: query.cookie, proxy: query.proxy }
|
||||
)
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "NeteaseCloudMusicApi",
|
||||
"version": "3.0.2",
|
||||
"version": "3.0.3",
|
||||
"description": "网易云音乐 NodeJS 版 API",
|
||||
"scripts": {
|
||||
"start": "node app.js",
|
||||
|
6
util/index.js
Normal file
6
util/index.js
Normal file
@ -0,0 +1,6 @@
|
||||
module.exports = {
|
||||
toBoolean(val) {
|
||||
if (val === '') return val
|
||||
return val === 'true' || val == '1'
|
||||
}
|
||||
}
|
169
util/request.js
169
util/request.js
@ -2,88 +2,103 @@ const encrypt = require('./crypto')
|
||||
const request = require('request')
|
||||
const queryString = require('querystring')
|
||||
|
||||
const chooseUserAgent = (ua) => {
|
||||
const userAgentList = [
|
||||
'Mozilla/5.0 (iPhone; CPU iPhone OS 9_1 like Mac OS X) AppleWebKit/601.1.46 (KHTML, like Gecko) Version/9.0 Mobile/13B143 Safari/601.1',
|
||||
'Mozilla/5.0 (iPhone; CPU iPhone OS 9_1 like Mac OS X) AppleWebKit/601.1.46 (KHTML, like Gecko) Version/9.0 Mobile/13B143 Safari/601.1',
|
||||
'Mozilla/5.0 (Linux; Android 5.0; SM-G900P Build/LRX21T) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.115 Mobile Safari/537.36',
|
||||
'Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.115 Mobile Safari/537.36',
|
||||
'Mozilla/5.0 (Linux; Android 5.1.1; Nexus 6 Build/LYZ28E) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.115 Mobile Safari/537.36',
|
||||
'Mozilla/5.0 (iPhone; CPU iPhone OS 10_3_2 like Mac OS X) AppleWebKit/603.2.4 (KHTML, like Gecko) Mobile/14F89;GameHelper',
|
||||
'Mozilla/5.0 (iPhone; CPU iPhone OS 10_0 like Mac OS X) AppleWebKit/602.1.38 (KHTML, like Gecko) Version/10.0 Mobile/14A300 Safari/602.1',
|
||||
'Mozilla/5.0 (iPad; CPU OS 10_0 like Mac OS X) AppleWebKit/602.1.38 (KHTML, like Gecko) Version/10.0 Mobile/14A300 Safari/602.1',
|
||||
'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.12; rv:46.0) Gecko/20100101 Firefox/46.0',
|
||||
'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.115 Safari/537.36',
|
||||
'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_5) AppleWebKit/603.2.4 (KHTML, like Gecko) Version/10.1.1 Safari/603.2.4',
|
||||
'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:46.0) Gecko/20100101 Firefox/46.0',
|
||||
'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.103 Safari/537.36',
|
||||
'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/42.0.2311.135 Safari/537.36 Edge/13.10586'
|
||||
]
|
||||
let index = 0
|
||||
if(typeof(ua) == 'undefined')
|
||||
index = Math.floor(Math.random() * userAgentList.length)
|
||||
else if(ua == 'mobile')
|
||||
index = Math.floor(Math.random() * 7)
|
||||
else if(ua == 'pc')
|
||||
index = Math.floor(Math.random() * 5) + 8
|
||||
else
|
||||
return ua
|
||||
return userAgentList[index]
|
||||
// request.debug = true // 开启可看到更详细信息
|
||||
|
||||
const chooseUserAgent = ua => {
|
||||
const userAgentList = [
|
||||
'Mozilla/5.0 (iPhone; CPU iPhone OS 9_1 like Mac OS X) AppleWebKit/601.1.46 (KHTML, like Gecko) Version/9.0 Mobile/13B143 Safari/601.1',
|
||||
'Mozilla/5.0 (iPhone; CPU iPhone OS 9_1 like Mac OS X) AppleWebKit/601.1.46 (KHTML, like Gecko) Version/9.0 Mobile/13B143 Safari/601.1',
|
||||
'Mozilla/5.0 (Linux; Android 5.0; SM-G900P Build/LRX21T) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.115 Mobile Safari/537.36',
|
||||
'Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.115 Mobile Safari/537.36',
|
||||
'Mozilla/5.0 (Linux; Android 5.1.1; Nexus 6 Build/LYZ28E) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.115 Mobile Safari/537.36',
|
||||
'Mozilla/5.0 (iPhone; CPU iPhone OS 10_3_2 like Mac OS X) AppleWebKit/603.2.4 (KHTML, like Gecko) Mobile/14F89;GameHelper',
|
||||
'Mozilla/5.0 (iPhone; CPU iPhone OS 10_0 like Mac OS X) AppleWebKit/602.1.38 (KHTML, like Gecko) Version/10.0 Mobile/14A300 Safari/602.1',
|
||||
'Mozilla/5.0 (iPad; CPU OS 10_0 like Mac OS X) AppleWebKit/602.1.38 (KHTML, like Gecko) Version/10.0 Mobile/14A300 Safari/602.1',
|
||||
'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.12; rv:46.0) Gecko/20100101 Firefox/46.0',
|
||||
'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.115 Safari/537.36',
|
||||
'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_5) AppleWebKit/603.2.4 (KHTML, like Gecko) Version/10.1.1 Safari/603.2.4',
|
||||
'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:46.0) Gecko/20100101 Firefox/46.0',
|
||||
'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.103 Safari/537.36',
|
||||
'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/42.0.2311.135 Safari/537.36 Edge/13.10586'
|
||||
]
|
||||
let index = 0
|
||||
if (typeof ua == 'undefined')
|
||||
index = Math.floor(Math.random() * userAgentList.length)
|
||||
else if (ua == 'mobile') index = Math.floor(Math.random() * 7)
|
||||
else if (ua == 'pc') index = Math.floor(Math.random() * 5) + 8
|
||||
else return ua
|
||||
return userAgentList[index]
|
||||
}
|
||||
|
||||
const createRequest = (method, url, data, options) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
let headers = { 'User-Agent': chooseUserAgent(options.ua) }
|
||||
if (method.toUpperCase() == 'POST')
|
||||
headers['Content-Type'] = 'application/x-www-form-urlencoded'
|
||||
if (url.includes('music.163.com'))
|
||||
headers['Referer'] = 'http://music.163.com'
|
||||
// headers['X-Real-IP'] = '118.88.88.88'
|
||||
|
||||
let headers = {'User-Agent': chooseUserAgent(options.ua)}
|
||||
if(method.toUpperCase() == 'POST') headers['Content-Type'] = 'application/x-www-form-urlencoded'
|
||||
if(url.includes('music.163.com')) headers['Referer'] = 'http://music.163.com'
|
||||
// headers['X-Real-IP'] = '118.88.88.88'
|
||||
|
||||
if(typeof(options.cookie) === 'object')
|
||||
headers['Cookie'] = Object.keys(options.cookie).map(key => (encodeURIComponent(key) + '=' + encodeURIComponent(options.cookie[key]))).join('; ')
|
||||
else if(options.cookie)
|
||||
headers['Cookie'] = options.cookie
|
||||
|
||||
if(options.crypto == 'weapi'){
|
||||
let csrfToken = (headers['Cookie'] || '').match(/_csrf=([^(;|$)]+)/)
|
||||
data.csrf_token = (csrfToken ? csrfToken[1] : '')
|
||||
data = encrypt.weapi(data)
|
||||
url = url.replace(/\w*api/,'weapi')
|
||||
}
|
||||
else if(options.crypto == 'linuxapi'){
|
||||
data = encrypt.linuxapi({'method': method, url: url.replace(/\w*api/,'api'), 'params': data})
|
||||
headers['User-Agent'] = 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.90 Safari/537.36'
|
||||
url = 'http://music.163.com/api/linux/forward'
|
||||
}
|
||||
|
||||
const answer = {status: 500, body: {}, cookie: []}
|
||||
request(
|
||||
{method: method, url: url, headers: headers, body: queryString.stringify(data), proxy: options.proxy},
|
||||
(err, res, body) => {
|
||||
if(err){
|
||||
answer.status = 502
|
||||
answer.body = {code: 502, msg: err.stack}
|
||||
reject(answer)
|
||||
}
|
||||
else{
|
||||
answer.cookie = (res.headers['set-cookie'] || []).map(x => x.replace(/\s*Domain=[^(;|$)]+;*/, ''))
|
||||
try{
|
||||
answer.body = JSON.parse(body)
|
||||
answer.status = answer.body.code || res.statusCode
|
||||
}
|
||||
catch(e){
|
||||
answer.body = body
|
||||
answer.status = res.statusCode
|
||||
}
|
||||
answer.status = (100 < answer.status && answer.status < 600) ? answer.status : 400
|
||||
if(answer.status == 200)
|
||||
resolve(answer)
|
||||
else
|
||||
reject(answer)
|
||||
}
|
||||
}
|
||||
if (typeof options.cookie === 'object')
|
||||
headers['Cookie'] = Object.keys(options.cookie)
|
||||
.map(
|
||||
key =>
|
||||
encodeURIComponent(key) +
|
||||
'=' +
|
||||
encodeURIComponent(options.cookie[key])
|
||||
)
|
||||
})
|
||||
.join('; ')
|
||||
else if (options.cookie) headers['Cookie'] = options.cookie
|
||||
|
||||
if (options.crypto == 'weapi') {
|
||||
let csrfToken = (headers['Cookie'] || '').match(/_csrf=([^(;|$)]+)/)
|
||||
data.csrf_token = csrfToken ? csrfToken[1] : ''
|
||||
data = encrypt.weapi(data)
|
||||
url = url.replace(/\w*api/, 'weapi')
|
||||
} else if (options.crypto == 'linuxapi') {
|
||||
data = encrypt.linuxapi({
|
||||
method: method,
|
||||
url: url.replace(/\w*api/, 'api'),
|
||||
params: data
|
||||
})
|
||||
headers['User-Agent'] =
|
||||
'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.90 Safari/537.36'
|
||||
url = 'http://music.163.com/api/linux/forward'
|
||||
}
|
||||
|
||||
const answer = { status: 500, body: {}, cookie: [] }
|
||||
request(
|
||||
{
|
||||
method: method,
|
||||
url: url,
|
||||
headers: headers,
|
||||
body: queryString.stringify(data),
|
||||
proxy: options.proxy
|
||||
},
|
||||
(err, res, body) => {
|
||||
if (err) {
|
||||
answer.status = 502
|
||||
answer.body = { code: 502, msg: err.stack }
|
||||
reject(answer)
|
||||
} else {
|
||||
answer.cookie = (res.headers['set-cookie'] || []).map(x =>
|
||||
x.replace(/\s*Domain=[^(;|$)]+;*/, '')
|
||||
)
|
||||
try {
|
||||
answer.body = JSON.parse(body)
|
||||
answer.status = answer.body.code || res.statusCode
|
||||
} catch (e) {
|
||||
answer.body = body
|
||||
answer.status = res.statusCode
|
||||
}
|
||||
answer.status =
|
||||
100 < answer.status && answer.status < 600 ? answer.status : 400
|
||||
if (answer.status == 200) resolve(answer)
|
||||
else reject(answer)
|
||||
}
|
||||
}
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
module.exports = createRequest
|
||||
|
Loading…
x
Reference in New Issue
Block a user