上传用到的域名:
https://developer.qiniu.com/kodo/1671/region-endpoint-fq
使用node生成上传凭证:
https://developer.qiniu.com/kodo/1289/nodejs#5
const qiniu = require('qiniu')
//获取上传凭证
const uploadGetToken = (req, res) => {
const { accessKey, secretKey } = getQiNiuKey()
const mac = new qiniu.auth.digest.Mac(accessKey, secretKey)
const putPolicy = new qiniu.rs.PutPolicy({
scope: 'xutongbao-video',
returnBody: `{
"code": 200,
"data": {"key":"$(key)","hash":"$(etag)","fsize":$(fsize),"bucket":"$(bucket)","file":"$(fname)"},
"message": "成功"
}`
})
const uploadToken = putPolicy.uploadToken(mac)
res.send({
code: 200,
data: {
token: uploadToken
},
message: '成功'
})
}
封装andt上传组件:
import React from 'react'
import { Button, Upload, message } from 'antd'
import { v4 as uuidv4 } from 'uuid'
import {
imageUrlFormat,
uploadGetTokenFromLocalStorage,
} from '../../utils/tools'
import urls from '../../api/urls'
export default function UploadImgToCND({
value = '',
msg,
type = 'add',
onChange,
accept = '*.*',
imgUrlCnd,
}) {
const imageUrl = imageUrlFormat(imgUrlCnd)
let defaultValue = {
uid: '-1',
name: imageUrl,
status: 'done',
url: imageUrl,
}
const fileList = []
if (value) {
fileList.push(defaultValue)
}
const uploadProps = {
name: 'file',
action: urls.light.uploadToCDN,
data: (file) => {
const uid = uuidv4()
const reslutIndex = Array.from(file.name).findLastIndex(item => item === '.')
const fileName = uid + file.name.slice(reslutIndex, file.name.length)
return {
key: `img/${fileName}`,
fname: fileName,
token: uploadGetTokenFromLocalStorage(),
}
},
headers: {},
maxCount: 1,
listType: 'picture',
defaultFileList: [...fileList],
accept,
onChange(info) {
if (info.file.status !== 'uploading') {
console.log(info.file, info.fileList)
onChange(undefined)
}
if (info.file.status === 'done') {
message.success(`${info.file.name} 上传成功`)
if (info.file.response.code === 200) {
// console.log(info.file.xhr.responseURL)
// const imgUrl = `${getHost(info.file.xhr.responseURL)}/${info.file.response.data.filename}`
// console.log(imgUrl)
onChange(info.file.response.data.key)
}
} else if (info.file.status === 'uploading') {
} else if (info.file.status === 'error') {
message.error(`${info.file.name} 上传失败`)
}
},
}
return (
<span>
{type !== 'check' ? (
<Upload {...uploadProps}>
<Button>上传图片</Button>
<span className="m-upload-text">{msg}</span>
</Upload>
) : (
value && (
<img
src={imageUrl}
alt={imageUrl}
className="m-upload-img-check"
></img>
)
)}
</span>
)
}
使用组件:
<Form.Item label="头像" name="avatar">
<UploadImgToCND imgUrlCnd={initValues.avatarCnd}></UploadImgToCND>
</Form.Item>
<Form.Item label="封面" name="coverImage">
<UploadImgToCND imgUrlCnd={initValues.coverImageCnd}></UploadImgToCND>
</Form.Item>
图片的路径链接转cdn链接:
//获取加密的图片链接
const getSecrecyImgUrl = (key) => {
if (key) {
const { accessKey, secretKey } = getQiNiuKey()
const mac = new qiniu.auth.digest.Mac(accessKey, secretKey)
const config = new qiniu.conf.Config()
const bucketManager = new qiniu.rs.BucketManager(mac, config)
//var privateBucketDomain = 'http://rewjm2mrh.hb-bkt.clouddn.com';
const privateBucketDomain = 'http://cdn.xutongbao.top'
const deadline = parseInt(Date.now() / 1000) + 3600 * 24 // 24小时过期
//const key = 'video/2.mp4'
const privateDownloadUrl = bucketManager.privateDownloadUrl(
privateBucketDomain,
key,
deadline
)
return privateDownloadUrl
} else {
return ''
}
}
上传时调用七牛云的接口,调用时需要带上token。数据库中保存的是图片的路径链接,并不是七牛云的cdn图片链接,访问列表时需要把图片的路径链接转成cdn链接给前端使用。前端修改图片时依然是只修改路径链接。