mirror of
https://gitlab.com/Binaryify/neteasecloudmusicapi.git
synced 2025-05-23 22:37:41 +08:00
v4.0,新增云盘上传接口以及二维码登录相关接口和相关demo,升级部分接口加密方法 #70 , #121 ,#121 , #153 ,#248 , #705 , #716 , #745 , #1055
This commit is contained in:
parent
77775b25f5
commit
75cb79fc6a
@ -1,3 +1,4 @@
|
||||
static
|
||||
docs
|
||||
node_modules
|
||||
node_modules
|
||||
module_example
|
||||
|
@ -1,4 +1,11 @@
|
||||
# 更新日志
|
||||
### 4.0.0 | 2021.1.03
|
||||
- 新增云盘上传接口,新增二维码登录相关接口和相关demo(http://localhost:3000/qrlogin.html, http://localhost:3000/cloud.html),更新 d.ts
|
||||
|
||||
- 升级部分接口加密方法("linuxapi" 都替换到了"api")
|
||||
|
||||
- 更新 `login/status` 接口(返回字段和之前不一样)
|
||||
|
||||
### 3.47.5 | 2020.12.20
|
||||
- 更新appver [#1060](https://github.com/Binaryify/NeteaseCloudMusicApi/issues/1060)
|
||||
|
||||
|
@ -213,6 +213,10 @@
|
||||
195. 关注歌手新歌
|
||||
196. 关注歌手新MV
|
||||
197. 歌手详情
|
||||
198. 云盘上传
|
||||
199. 二维码登录
|
||||
200. 话题详情
|
||||
201. 话题详情热门动态
|
||||
|
||||
## 安装
|
||||
|
||||
@ -359,7 +363,7 @@ $ sudo docker run -d -p 3000:3000 netease-music-api
|
||||
|
||||
!> 部分接口如登录接口不能调用太频繁 , 否则可能会触发 503 错误或者 ip 高频错误 ,若需频繁调用 , 需要准备 IP 代理池 (更新:已加入缓存机制,但仍需注意).
|
||||
|
||||
!> 本项目仅供学习使用,请尊重版权,请勿利用此项目从事商业行为
|
||||
!> 本项目仅供学习使用,请尊重版权,请勿利用此项目从事商业行为或进行破坏版权行为
|
||||
|
||||
!> 文档可能会有缓存 , 如果文档版本和 github 上的版本不一致,请清除缓存再查看
|
||||
|
||||
@ -420,22 +424,34 @@ v3.30.0后支持手动传入cookie,登录接口返回内容新增 `cookie` 字
|
||||
}
|
||||
```
|
||||
#### 3. 二维码登录
|
||||
说明: 二维码登录涉及到3个接口
|
||||
1. 二维码key生成接口
|
||||
说明: 调用此接口可生成一个key
|
||||
说明: 二维码登录涉及到3个接口,调用务必带上时间戳,防止缓存
|
||||
##### 1. 二维码key生成接口
|
||||
|
||||
说明: 调用此接口可生成一个key
|
||||
|
||||
**接口地址 :** `/login/qr/key`
|
||||
##### 2. 二维码生成接口
|
||||
说明: 调用此接口传入上一个接口生成的key可生成二维码图片的base64和二维码信息,可使用base64展示图片,或者使用二维码信息内容自行使用第三方二维码生产库渲染二维码
|
||||
|
||||
2. 二维码生成接口
|
||||
说明: 调用此接口传入上一个接口生成的key可生成二维码图片的base64和二维码信息,可使用base64展示图片,或者使用二维码信息内容自行使用第三方二维码生产库渲染二维码
|
||||
可选参数: `qrimg` 传入后
|
||||
**接口地址 :** `/login/qr/create`
|
||||
必选参数: `key`,由第一个接口生成
|
||||
|
||||
可选参数: `qrimg` 传入后会额外返回二维码图片base64编码
|
||||
|
||||
**接口地址 :** `/login/qr/create`
|
||||
|
||||
**调用例子 :** `/login/qr/create?key=xxx`
|
||||
|
||||
|
||||
3. 二维码检测扫码状态接口
|
||||
说明: 轮询此接口可获取二维码扫码状态,801为等待扫码,802为待确认,803为授权登陆成功
|
||||
##### 3. 二维码检测扫码状态接口
|
||||
说明: 轮询此接口可获取二维码扫码状态,800为二维码过期,801为等待扫码,802为待确认,803为授权登录成功(803状态码下会返回cookies)
|
||||
|
||||
必选参数: `key`,由第一个接口生成
|
||||
|
||||
**接口地址 :** `/login/qr/check`
|
||||
|
||||
**调用例子 :** `/login/qr/check?key=xxx`
|
||||
|
||||
调用可参考项目文件例子`/public/qrlogin.html` (访问地址:http://localhost:3000/qrlogin.html)
|
||||
|
||||
|
||||
#### 注意
|
||||
@ -640,7 +656,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),支持命令行调用,参考module_example目录下`avatar_upload.js`
|
||||
|
||||
**可选参数 :**
|
||||
|
||||
@ -936,6 +952,21 @@ tags: 歌单标签
|
||||
|
||||
**调用例子 :** `/hot/topic?limit=30&offset=30`
|
||||
|
||||
### 获取话题详情
|
||||
|
||||
说明 : 调用此接口 , 可获取话题详情
|
||||
|
||||
**接口地址 :** `/topic/detail`
|
||||
|
||||
**调用例子 :** `/topic/detail?actid=111551188`
|
||||
### 获取话题详情热门动态
|
||||
|
||||
说明 : 调用此接口 , 可获取话题详情热门动态
|
||||
|
||||
**接口地址 :** `/topic/detail/event/hot`
|
||||
|
||||
**调用例子 :** `/topic/detail/event/hot?actid=111551188`
|
||||
|
||||
|
||||
### 云村热评
|
||||
说明 : 登录后调用此接口 , 可获取云村热评
|
||||
@ -1238,10 +1269,6 @@ mp3url 不能直接用 , 可通过 `/song/url` 接口传入歌曲 id 获取具
|
||||
|
||||
**调用例子 :** `/search?keywords= 海阔天空` `/cloudsearch?keywords= 海阔天空`
|
||||
|
||||
返回数据如下图 :
|
||||

|
||||
|
||||
|
||||
### 默认搜索关键词
|
||||
说明 : 调用此接口 , 可获取默认搜索关键词
|
||||
|
||||
@ -1443,8 +1470,7 @@ mp3url 不能直接用 , 可通过 `/song/url` 接口传入歌曲 id 获取具
|
||||
|
||||
### 歌曲评论
|
||||
|
||||
说明 : 调用此接口 , 传入音乐 id 和 limit 参数 , 可获得该音乐的所有评论 ( 不需要
|
||||
登录 )
|
||||
说明 : 调用此接口 , 传入音乐 id 和 limit 参数 , 可获得该音乐的所有评论 ( 不需要登录 )
|
||||
|
||||
**必选参数 :** `id`: 音乐 id
|
||||
|
||||
@ -2553,6 +2579,19 @@ type : 地区
|
||||
|
||||
**调用例子 :** `/user/cloud/del`
|
||||
|
||||
### 云盘上传
|
||||
说明 : 登录后调用此接口,使用`'Content-Type': 'multipart/form-data'`上传mp3 formData(name为'songFile'),可上传歌曲到云盘
|
||||
|
||||
参考: https://github.com/Binaryify/NeteaseCloudMusicApi/blob/master/public/cloud.html
|
||||
|
||||
访问地址: http://localhost:3000/qrlogin.html)
|
||||
|
||||
支持命令行调用,参考module_example目录下`song_upload.js`
|
||||
|
||||
**接口地址 :** `/cloud`
|
||||
|
||||
**调用例子 :** `/cloud`
|
||||
|
||||
### 电台banner
|
||||
说明 : 调用此接口,可获取电台banner
|
||||
|
||||
|
29
interface.d.ts
vendored
29
interface.d.ts
vendored
@ -1360,3 +1360,32 @@ export function artist_detail(
|
||||
id: number | string
|
||||
} & RequestBaseConfig,
|
||||
): Promise<Response>
|
||||
|
||||
export function cloud(params: RequestBaseConfig): Promise<Response>
|
||||
|
||||
export function topic_detail(
|
||||
params: {
|
||||
actid?: number | string
|
||||
} & RequestBaseConfig,
|
||||
): Promise<Response>
|
||||
|
||||
export function topic_detail_event_hot(
|
||||
params: {
|
||||
actid?: number | string
|
||||
} & RequestBaseConfig,
|
||||
): Promise<Response>
|
||||
|
||||
export function login_qr_key(params: RequestBaseConfig): Promise<Response>
|
||||
|
||||
export function login_qr_create(
|
||||
params: {
|
||||
key?: number | string
|
||||
qrimg?: boolean | string
|
||||
} & RequestBaseConfig,
|
||||
): Promise<Response>
|
||||
|
||||
export function login_qr_check(
|
||||
params: {
|
||||
key?: number | string
|
||||
} & RequestBaseConfig,
|
||||
): Promise<Response>
|
||||
|
@ -12,6 +12,6 @@ module.exports = (query, request) => {
|
||||
'POST',
|
||||
`https://music.163.com/api/v2/banner/get`,
|
||||
{ clientType: type },
|
||||
{ crypto: 'linuxapi', proxy: query.proxy, realIP: query.realIP },
|
||||
{ crypto: 'api', proxy: query.proxy, realIP: query.realIP },
|
||||
)
|
||||
}
|
||||
|
132
module/cloud.js
Normal file
132
module/cloud.js
Normal file
@ -0,0 +1,132 @@
|
||||
const mm = require('music-metadata')
|
||||
const uploadPlugin = require('../plugins/songUpload')
|
||||
const md5 = require('md5')
|
||||
module.exports = async (query, request) => {
|
||||
query.cookie.os = 'pc'
|
||||
query.cookie.appver = '2.7.1.198277'
|
||||
const bitrate = 999000
|
||||
if (!query.songFile) {
|
||||
return Promise.reject({
|
||||
status: 500,
|
||||
body: {
|
||||
msg: '请上传音乐文件',
|
||||
code: 500,
|
||||
},
|
||||
})
|
||||
}
|
||||
if (!query.songFile.md5) {
|
||||
// 命令行上传没有md5和size信息,需要填充
|
||||
query.songFile.md5 = md5(query.songFile.data)
|
||||
query.songFile.size = query.songFile.data.byteLength
|
||||
}
|
||||
const res = await request(
|
||||
'POST',
|
||||
`https://interface.music.163.com/api/cloud/upload/check`,
|
||||
{
|
||||
bitrate: String(bitrate),
|
||||
ext: '',
|
||||
length: query.songFile.size,
|
||||
md5: query.songFile.md5,
|
||||
songId: '0',
|
||||
version: 1,
|
||||
},
|
||||
{
|
||||
crypto: 'weapi',
|
||||
cookie: query.cookie,
|
||||
proxy: query.proxy,
|
||||
realIP: query.realIP,
|
||||
},
|
||||
)
|
||||
let artist = ''
|
||||
let album = ''
|
||||
let songName = ''
|
||||
try {
|
||||
const metadata = await mm.parseBuffer(query.songFile.data, 'audio/mpeg')
|
||||
if (metadata.native.ID3v1) {
|
||||
metadata.native.ID3v1.forEach((item) => {
|
||||
// console.log(item.id, item.value)
|
||||
if (item.id === 'title') {
|
||||
songName = item.value
|
||||
}
|
||||
if (item.id === 'artist') {
|
||||
artist = item.value
|
||||
}
|
||||
if (item.id === 'album') {
|
||||
album = item.value
|
||||
}
|
||||
})
|
||||
// console.log({
|
||||
// songName,
|
||||
// album,
|
||||
// songName,
|
||||
// })
|
||||
}
|
||||
} catch (error) {
|
||||
console.log(error)
|
||||
}
|
||||
const tokenRes = await request(
|
||||
'POST',
|
||||
`https://music.163.com/weapi/nos/token/alloc`,
|
||||
{
|
||||
bucket: '',
|
||||
ext: 'mp3',
|
||||
filename: query.songFile.name.replace('.mp3', ''),
|
||||
local: false,
|
||||
nos_product: 3,
|
||||
type: 'audio',
|
||||
md5: query.songFile.md5,
|
||||
},
|
||||
{ crypto: 'weapi', cookie: query.cookie, proxy: query.proxy },
|
||||
)
|
||||
|
||||
if (res.body.needUpload) {
|
||||
const uploadInfo = await uploadPlugin(query, request)
|
||||
// console.log('uploadInfo', uploadInfo.body.result.resourceId)
|
||||
}
|
||||
// console.log(tokenRes.body.result)
|
||||
const res2 = await request(
|
||||
'POST',
|
||||
`https://music.163.com/api/upload/cloud/info/v2`,
|
||||
{
|
||||
md5: query.songFile.md5,
|
||||
songid: res.body.songId,
|
||||
filename: query.songFile.name,
|
||||
song: songName || query.songFile.name.replace('.mp3', ''),
|
||||
album: album || '未知专辑',
|
||||
artist: artist || '未知艺术家',
|
||||
bitrate: String(bitrate),
|
||||
resourceId: tokenRes.body.result.resourceId,
|
||||
},
|
||||
{
|
||||
crypto: 'weapi',
|
||||
cookie: query.cookie,
|
||||
proxy: query.proxy,
|
||||
realIP: query.realIP,
|
||||
},
|
||||
)
|
||||
// console.log({ res2, privateCloud: res2.body.privateCloud })
|
||||
// console.log(res.body.songId, 'songid')
|
||||
const res3 = await request(
|
||||
'POST',
|
||||
`https://interface.music.163.com/api/cloud/pub/v2`,
|
||||
{
|
||||
songid: res2.body.songId,
|
||||
},
|
||||
{
|
||||
crypto: 'weapi',
|
||||
cookie: query.cookie,
|
||||
proxy: query.proxy,
|
||||
realIP: query.realIP,
|
||||
},
|
||||
)
|
||||
// console.log({ res3 })
|
||||
return {
|
||||
status: 200,
|
||||
body: {
|
||||
...res.body,
|
||||
...res3.body,
|
||||
// ...uploadInfo,
|
||||
},
|
||||
cookie: res.cookie,
|
||||
}
|
||||
}
|
@ -5,7 +5,7 @@ module.exports = (query, request) => {
|
||||
limit: query.limit || 20,
|
||||
offset: query.offset || 0,
|
||||
}
|
||||
return request('POST', `https://music.163.com/weapi/act/hot`, data, {
|
||||
return request('POST', `https://music.163.com/api/act/hot`, data, {
|
||||
crypto: 'weapi',
|
||||
cookie: query.cookie,
|
||||
proxy: query.proxy,
|
||||
|
@ -16,10 +16,8 @@ module.exports = async (query, request) => {
|
||||
return {
|
||||
status: 200,
|
||||
body: {
|
||||
data: {
|
||||
...result.body,
|
||||
code: 200,
|
||||
},
|
||||
data: result.body,
|
||||
code: 200,
|
||||
},
|
||||
cookie: result.cookie,
|
||||
}
|
||||
|
@ -9,7 +9,7 @@ module.exports = (query, request) => {
|
||||
tv: -1,
|
||||
}
|
||||
return request('POST', `https://music.163.com/api/song/lyric`, data, {
|
||||
crypto: 'linuxapi',
|
||||
crypto: 'api',
|
||||
cookie: query.cookie,
|
||||
proxy: query.proxy,
|
||||
realIP: query.realIP,
|
||||
|
@ -7,7 +7,7 @@ module.exports = (query, request) => {
|
||||
s: query.s || 8,
|
||||
}
|
||||
return request('POST', `https://music.163.com/api/v6/playlist/detail`, data, {
|
||||
crypto: 'linuxapi',
|
||||
crypto: 'api',
|
||||
cookie: query.cookie,
|
||||
proxy: query.proxy,
|
||||
realIP: query.realIP,
|
||||
|
11
module/topic_detail.js
Normal file
11
module/topic_detail.js
Normal file
@ -0,0 +1,11 @@
|
||||
module.exports = (query, request) => {
|
||||
const data = {
|
||||
actid: query.actid,
|
||||
}
|
||||
return request('POST', `https://music.163.com/api/act/detail`, data, {
|
||||
crypto: 'weapi',
|
||||
cookie: query.cookie,
|
||||
proxy: query.proxy,
|
||||
realIP: query.realIP,
|
||||
})
|
||||
}
|
11
module/topic_detail_event_hot.js
Normal file
11
module/topic_detail_event_hot.js
Normal file
@ -0,0 +1,11 @@
|
||||
module.exports = (query, request) => {
|
||||
const data = {
|
||||
actid: query.actid,
|
||||
}
|
||||
return request('POST', `https://music.163.com/api/act/event/hot`, data, {
|
||||
crypto: 'weapi',
|
||||
cookie: query.cookie,
|
||||
proxy: query.proxy,
|
||||
realIP: query.realIP,
|
||||
})
|
||||
}
|
@ -6,7 +6,7 @@ module.exports = (query, request) => {
|
||||
`https://music.163.com/api/toplist`,
|
||||
{},
|
||||
{
|
||||
crypto: 'linuxapi',
|
||||
crypto: 'api',
|
||||
cookie: query.cookie,
|
||||
proxy: query.proxy,
|
||||
realIP: query.realIP,
|
||||
|
@ -5,7 +5,7 @@ module.exports = (query, request) => {
|
||||
limit: query.limit || 30,
|
||||
offset: query.offset || 0,
|
||||
}
|
||||
return request('POST', `https://music.163.com/weapi/v1/cloud/get`, data, {
|
||||
return request('POST', `https://music.163.com/api/v1/cloud/get`, data, {
|
||||
crypto: 'weapi',
|
||||
cookie: query.cookie,
|
||||
proxy: query.proxy,
|
||||
|
23
module_example/song_upload.js
Normal file
23
module_example/song_upload.js
Normal file
@ -0,0 +1,23 @@
|
||||
const { cloud, login_cellphone } = require('../main')
|
||||
const fs = require('fs')
|
||||
const path = require('path')
|
||||
|
||||
async function main() {
|
||||
const result = await login_cellphone({
|
||||
phone: '手机号',
|
||||
password: '密码',
|
||||
})
|
||||
const filePath = './test.mp3'
|
||||
try {
|
||||
await cloud({
|
||||
songFile: {
|
||||
name: path.basename(filePath),
|
||||
data: fs.readFileSync(filePath),
|
||||
},
|
||||
cookie: result.body.cookie,
|
||||
})
|
||||
} catch (error) {
|
||||
console.log(error, 'error')
|
||||
}
|
||||
}
|
||||
main()
|
BIN
module_example/test.mp3
Normal file
BIN
module_example/test.mp3
Normal file
Binary file not shown.
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "NeteaseCloudMusicApi",
|
||||
"version": "3.47.5",
|
||||
"version": "4.0.0",
|
||||
"description": "网易云音乐 NodeJS 版 API",
|
||||
"scripts": {
|
||||
"start": "node app.js",
|
||||
@ -39,6 +39,8 @@
|
||||
"axios": "^0.20.0",
|
||||
"express": "^4.17.1",
|
||||
"express-fileupload": "^1.1.9",
|
||||
"md5": "^2.3.0",
|
||||
"music-metadata": "^7.5.3",
|
||||
"pac-proxy-agent": "^4.0.0",
|
||||
"qrcode": "^1.4.4",
|
||||
"tunnel": "^0.0.6"
|
||||
|
39
plugins/songUpload.js
Normal file
39
plugins/songUpload.js
Normal file
@ -0,0 +1,39 @@
|
||||
const axios = require('axios')
|
||||
module.exports = async (query, request) => {
|
||||
// 获取key和token
|
||||
const tokenRes = await request(
|
||||
'POST',
|
||||
`https://music.163.com/weapi/nos/token/alloc`,
|
||||
{
|
||||
bucket: '',
|
||||
ext: 'mp3',
|
||||
filename: query.songFile.name.replace('.mp3', ''),
|
||||
local: false,
|
||||
nos_product: 3,
|
||||
type: 'audio',
|
||||
md5: query.songFile.md5,
|
||||
},
|
||||
{ crypto: 'weapi', cookie: query.cookie, proxy: query.proxy },
|
||||
)
|
||||
|
||||
// 上传
|
||||
const objectKey = tokenRes.body.result.objectKey.replace('/', '%2F')
|
||||
try {
|
||||
await axios({
|
||||
method: 'post',
|
||||
url: `http://45.127.129.8/ymusic/${objectKey}?offset=0&complete=true&version=1.0`,
|
||||
headers: {
|
||||
'x-nos-token': tokenRes.body.result.token,
|
||||
'Content-MD5': query.songFile.md5,
|
||||
'Content-Type': 'audio/mpeg',
|
||||
'Content-Length': String(query.songFile.size),
|
||||
},
|
||||
data: query.songFile.data,
|
||||
})
|
||||
} catch (error) {
|
||||
console.log('error', error.response)
|
||||
}
|
||||
return {
|
||||
...tokenRes,
|
||||
}
|
||||
}
|
@ -1,82 +1,82 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>更新头像</title>
|
||||
</head>
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>更新头像</title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<input id="file" type="file" name="filename" />
|
||||
<img id="avatar" style="height: 200px; width: 200px; border-radius: 50%;" />
|
||||
<script src="https://cdn.bootcdn.net/ajax/libs/axios/0.20.0-0/axios.min.js
|
||||
<body>
|
||||
<input id="file" type="file" />
|
||||
<img id="avatar" style="height: 200px; width: 200px; border-radius: 50%" />
|
||||
<script src="https://cdn.bootcdn.net/ajax/libs/axios/0.20.0-0/axios.min.js
|
||||
"></script>
|
||||
<script>
|
||||
const phone = ''
|
||||
const password = ''
|
||||
let cookieToken = ''
|
||||
if (!phone || !password) {
|
||||
const msg = '请设置你的手机号码和密码'
|
||||
alert(msg)
|
||||
throw new Error(msg)
|
||||
}
|
||||
<script>
|
||||
const phone = ''
|
||||
const password = ''
|
||||
let cookieToken = ''
|
||||
if (!phone || !password) {
|
||||
const msg = '请设置你的手机号码和密码'
|
||||
alert(msg)
|
||||
throw new Error(msg)
|
||||
}
|
||||
|
||||
main()
|
||||
login()
|
||||
async function main() {
|
||||
document.querySelector('input[type="file"]').addEventListener(
|
||||
'change',
|
||||
function (e) {
|
||||
var file = this.files[0]
|
||||
upload(file)
|
||||
},
|
||||
false
|
||||
)
|
||||
const res = await axios({
|
||||
url: `/user/detail?uid=32953014×tamp=${Date.now()}`,
|
||||
withCredentials: true, //关键
|
||||
})
|
||||
document.querySelector('#avatar').src = res.data.profile.avatarUrl
|
||||
}
|
||||
async function login() {
|
||||
const res = await axios({
|
||||
url: `/login/cellphone?phone=${phone}&password=${password}`,
|
||||
withCredentials: true, //关键
|
||||
})
|
||||
cookieToken = res.data.cookie
|
||||
}
|
||||
async function upload(file) {
|
||||
var formData = new FormData()
|
||||
formData.append('imgFile', file)
|
||||
const imgSize = await getImgSize(file)
|
||||
const res = await axios({
|
||||
method: 'post',
|
||||
url: `http://localhost:3000/avatar/upload?cookie=${cookieToken}&imgSize=${imgSize.width}&imgX=0&imgY=0×tamp=${Date.now()}`,
|
||||
headers: {
|
||||
'Content-Type': 'multipart/form-data',
|
||||
},
|
||||
data: formData,
|
||||
})
|
||||
document.querySelector('#avatar').src = res.data.data.url
|
||||
}
|
||||
function getImgSize(file) {
|
||||
return new Promise((resolve, reject) => {
|
||||
let reader = new FileReader()
|
||||
reader.readAsDataURL(file)
|
||||
reader.onload = function (theFile) {
|
||||
let image = new Image()
|
||||
image.src = theFile.target.result
|
||||
image.onload = function () {
|
||||
resolve({
|
||||
width: this.width,
|
||||
height: this.height
|
||||
})
|
||||
main()
|
||||
login()
|
||||
async function main() {
|
||||
document.querySelector('input[type="file"]').addEventListener(
|
||||
'change',
|
||||
function (e) {
|
||||
var file = this.files[0]
|
||||
upload(file)
|
||||
},
|
||||
false,
|
||||
)
|
||||
const res = await axios({
|
||||
url: `/user/detail?uid=32953014×tamp=${Date.now()}`,
|
||||
withCredentials: true, //关键
|
||||
})
|
||||
document.querySelector('#avatar').src = res.data.profile.avatarUrl
|
||||
}
|
||||
async function login() {
|
||||
const res = await axios({
|
||||
url: `/login/cellphone?phone=${phone}&password=${password}`,
|
||||
withCredentials: true, //关键
|
||||
})
|
||||
cookieToken = res.data.cookie
|
||||
}
|
||||
async function upload(file) {
|
||||
var formData = new FormData()
|
||||
formData.append('imgFile', file)
|
||||
const imgSize = await getImgSize(file)
|
||||
const res = await axios({
|
||||
method: 'post',
|
||||
url: `http://localhost:3000/avatar/upload?cookie=${cookieToken}&imgSize=${
|
||||
imgSize.width
|
||||
}&imgX=0&imgY=0×tamp=${Date.now()}`,
|
||||
headers: {
|
||||
'Content-Type': 'multipart/form-data',
|
||||
},
|
||||
data: formData,
|
||||
})
|
||||
document.querySelector('#avatar').src = res.data.data.url
|
||||
}
|
||||
function getImgSize(file) {
|
||||
return new Promise((resolve, reject) => {
|
||||
let reader = new FileReader()
|
||||
reader.readAsDataURL(file)
|
||||
reader.onload = function (theFile) {
|
||||
let image = new Image()
|
||||
image.src = theFile.target.result
|
||||
image.onload = function () {
|
||||
resolve({
|
||||
width: this.width,
|
||||
height: this.height,
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
})
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
55
public/cloud.html
Normal file
55
public/cloud.html
Normal file
@ -0,0 +1,55 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>云盘上传</title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<input id="file" type="file" accept="audio/mpeg" />
|
||||
|
||||
<script src="https://cdn.bootcdn.net/ajax/libs/axios/0.20.0-0/axios.min.js"></script>
|
||||
<script>
|
||||
|
||||
const phone = ''
|
||||
const password = ''
|
||||
let cookieToken = ''
|
||||
if (!phone || !password) {
|
||||
const msg = '请设置你的手机号码和密码'
|
||||
alert(msg)
|
||||
throw new Error(msg)
|
||||
}
|
||||
login()
|
||||
main()
|
||||
async function login() {
|
||||
const res = await axios({
|
||||
url: `/login/cellphone?phone=${phone}&password=${password}`,
|
||||
withCredentials: true, //关键
|
||||
})
|
||||
cookieToken = res.data.cookie
|
||||
}
|
||||
async function main() {
|
||||
document
|
||||
.querySelector('input[type="file"]')
|
||||
.addEventListener('change', function (e) {
|
||||
var file = this.files[0]
|
||||
upload(file)
|
||||
})
|
||||
}
|
||||
|
||||
async function upload(file) {
|
||||
var formData = new FormData()
|
||||
formData.append('songFile', file)
|
||||
const res = await axios({
|
||||
method: 'post',
|
||||
url: `http://localhost:3000/cloud?time=${Date.now()}`,
|
||||
headers: {
|
||||
'Content-Type': 'multipart/form-data',
|
||||
},
|
||||
data: formData,
|
||||
})
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
@ -1,88 +1,89 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>歌单封面上传</title>
|
||||
</head>
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>歌单封面上传</title>
|
||||
</head>
|
||||
<body>
|
||||
<input id="file" type="file" name="filename" />
|
||||
<img
|
||||
id="playlist_cover"
|
||||
style="height: 200px; width: 200px; border-radius: 50%"
|
||||
/>
|
||||
<script src="https://cdn.bootcdn.net/ajax/libs/axios/0.20.0-0/axios.min.js"></script>
|
||||
<script>
|
||||
const phone = ''
|
||||
const password = ''
|
||||
const playlist_id = ''
|
||||
let cookieToken = ''
|
||||
if (!phone || !password) {
|
||||
const msg = '请设置你的手机号码和密码'
|
||||
alert(msg)
|
||||
throw new Error(msg)
|
||||
}
|
||||
if (!playlist_id) {
|
||||
const msg = '请设置你的歌单id'
|
||||
alert(msg)
|
||||
throw new Error(msg)
|
||||
}
|
||||
|
||||
<body>
|
||||
|
||||
<input id="file" type="file" name="filename" />
|
||||
<img id="playlist_cover" style="height: 200px; width: 200px; border-radius: 50%;" />
|
||||
<script src="https://cdn.bootcdn.net/ajax/libs/axios/0.20.0-0/axios.min.js
|
||||
"></script>
|
||||
<script>
|
||||
const phone = ''
|
||||
const password = ''
|
||||
const playlist_id = ''
|
||||
let cookieToken = ''
|
||||
if (!phone || !password) {
|
||||
const msg = '请设置你的手机号码和密码'
|
||||
alert(msg)
|
||||
throw new Error(msg)
|
||||
}
|
||||
if (!playlist_id) {
|
||||
const msg = '请设置你的歌单id'
|
||||
alert(msg)
|
||||
throw new Error(msg)
|
||||
}
|
||||
|
||||
main()
|
||||
login()
|
||||
async function main() {
|
||||
document.querySelector('input[type="file"]').addEventListener(
|
||||
'change',
|
||||
function (e) {
|
||||
var file = this.files[0]
|
||||
upload(file)
|
||||
},
|
||||
false
|
||||
)
|
||||
const res = await axios({
|
||||
url: `/playlist/detail?id=${playlist_id}×tamp=${Date.now()}`,
|
||||
})
|
||||
document.querySelector('#playlist_cover').src = res.data.playlist.coverImgUrl
|
||||
}
|
||||
async function login() {
|
||||
const res = await axios({
|
||||
url: `/login/cellphone?phone=${phone}&password=${password}`,
|
||||
withCredentials: true, //关键
|
||||
})
|
||||
cookieToken = res.data.cookie
|
||||
}
|
||||
async function upload(file) {
|
||||
var formData = new FormData()
|
||||
formData.append('imgFile', file)
|
||||
const imgSize = await getImgSize(file)
|
||||
const res = await axios({
|
||||
method: 'post',
|
||||
url: `http://localhost:3000/playlist/cover/update?id=${playlist_id}&cookie=${cookieToken}&imgSize=${imgSize.width}&imgX=0&imgY=0×tamp=${Date.now()}`,
|
||||
headers: {
|
||||
'Content-Type': 'multipart/form-data',
|
||||
},
|
||||
data: formData,
|
||||
})
|
||||
document.querySelector('#playlist_cover').src = res.data.data.url
|
||||
}
|
||||
function getImgSize(file) {
|
||||
return new Promise((resolve, reject) => {
|
||||
let reader = new FileReader()
|
||||
reader.readAsDataURL(file)
|
||||
reader.onload = function (theFile) {
|
||||
let image = new Image()
|
||||
image.src = theFile.target.result
|
||||
image.onload = function () {
|
||||
resolve({
|
||||
width: this.width,
|
||||
height: this.height,
|
||||
})
|
||||
main()
|
||||
login()
|
||||
async function main() {
|
||||
document.querySelector('input[type="file"]').addEventListener(
|
||||
'change',
|
||||
function (e) {
|
||||
var file = this.files[0]
|
||||
upload(file)
|
||||
},
|
||||
false,
|
||||
)
|
||||
const res = await axios({
|
||||
url: `/playlist/detail?id=${playlist_id}×tamp=${Date.now()}`,
|
||||
})
|
||||
document.querySelector('#playlist_cover').src = res.data.playlist.coverImgUrl
|
||||
}
|
||||
async function login() {
|
||||
const res = await axios({
|
||||
url: `/login/cellphone?phone=${phone}&password=${password}`,
|
||||
withCredentials: true, //关键
|
||||
})
|
||||
cookieToken = res.data.cookie
|
||||
}
|
||||
async function upload(file) {
|
||||
var formData = new FormData()
|
||||
formData.append('imgFile', file)
|
||||
const imgSize = await getImgSize(file)
|
||||
const res = await axios({
|
||||
method: 'post',
|
||||
url: `http://localhost:3000/playlist/cover/update?id=${playlist_id}&cookie=${cookieToken}&imgSize=${
|
||||
imgSize.width
|
||||
}&imgX=0&imgY=0×tamp=${Date.now()}`,
|
||||
headers: {
|
||||
'Content-Type': 'multipart/form-data',
|
||||
},
|
||||
data: formData,
|
||||
})
|
||||
document.querySelector('#playlist_cover').src = res.data.data.url
|
||||
}
|
||||
function getImgSize(file) {
|
||||
return new Promise((resolve, reject) => {
|
||||
let reader = new FileReader()
|
||||
reader.readAsDataURL(file)
|
||||
reader.onload = function (theFile) {
|
||||
let image = new Image()
|
||||
image.src = theFile.target.result
|
||||
image.onload = function () {
|
||||
resolve({
|
||||
width: this.width,
|
||||
height: this.height,
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
})
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
@ -23,36 +23,36 @@
|
||||
$.ajax({
|
||||
url: `/login/cellphone?phone=${phone}&password=${password}`,
|
||||
xhrFields: {
|
||||
withCredentials: true //关键
|
||||
withCredentials: true, //关键
|
||||
},
|
||||
success: function (data) {
|
||||
console.log(data)
|
||||
$.ajax({
|
||||
url: `/recommend/resource `,
|
||||
xhrFields: {
|
||||
withCredentials: true //关键
|
||||
withCredentials: true, //关键
|
||||
},
|
||||
success: function (data) {
|
||||
console.log(data)
|
||||
},
|
||||
error: function (err) {
|
||||
console.log(err)
|
||||
}
|
||||
},
|
||||
})
|
||||
},
|
||||
error: function (err) {
|
||||
console.log(err)
|
||||
}
|
||||
},
|
||||
})
|
||||
|
||||
axios({
|
||||
url: `/login/cellphone?phone=${phone}&password=${password}`,
|
||||
withCredentials: true //关键
|
||||
withCredentials: true, //关键
|
||||
}).then(function (res) {
|
||||
console.log(res.data)
|
||||
axios({
|
||||
url: `/recommend/resource`,
|
||||
withCredentials: true //关键
|
||||
withCredentials: true, //关键
|
||||
}).then(function (res) {
|
||||
console.log(res.data)
|
||||
})
|
||||
@ -60,4 +60,4 @@
|
||||
</script>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
</html>
|
||||
|
Loading…
x
Reference in New Issue
Block a user