相关视频地址:www.bilibili.com/video/BV1ct…
在wangEditor中把图片上传到七牛云保存,以NextJS框架为例进行展示。
wangEditorwww.wangeditor.com/
安装基本的依赖包
npm i @wangeditor/editor @wangeditor/editor-for-react qiniu qiniu-js uuid
在环境变量中写入七牛配置
// 七牛空间名
QINIU_BUCKET = XXXXXXXXXX
// 七牛云的 AK 和 SK
QINIU_AK = XXXXXXXXXXXXXXXXXX
QINIU_SK = XXXXXXXXXXXXXXXXXXX
// 七牛云的 CDN 地址
NEXT_PUBLIC_CDN = XXXXXXXXXXXXXXXX
在前端创建wangEditor组件
'use client';
import '@wangeditor/editor/dist/css/style.css'; // 引入 css
import React, { useState, useEffect } from 'react';
import { Editor, Toolbar } from '@wangeditor/editor-for-react';
import { IDomEditor, IEditorConfig, IToolbarConfig } from '@wangeditor/editor';
import { v4 as uuidv4 } from 'uuid';
import * as qiniu from 'qiniu-js'
type InsertFnType = (url: string, alt: string, href: string) => void
function MyEditor({ html, setHtml }: { html: string; setHtml: any }) {
// editor 实例
const [editor, setEditor] = useState<IDomEditor | null>(null); // TS 语法
// const [editor, setEditor] = useState(null) // JS 语法
// 模拟 ajax 请求,异步设置 html
useEffect(() => {
// setTimeout(() => {
// setHtml('<p>hello world</p>');
// }, 1500);
}, []);
// 获取七牛云上传 token
const getToken = async (key: string) => {
const res = await fetch(`/api/admin/upload/token?key=${key}`);
const data = await res.json();
return data.token;
}
// cdn
const cnd = process.env.NEXT_PUBLIC_CDN;
// 工具栏配置
const toolbarConfig: Partial<IToolbarConfig> = {}; // TS 语法
// const toolbarConfig = { } // JS 语法
// 编辑器配置
const editorConfig: Partial<IEditorConfig> = {
// TS 语法
// const editorConfig = { // JS 语法
placeholder: '请输入内容...',
MENU_CONF: {
uploadImage: {
async customUpload(file: File, insertFn: InsertFnType) { // TS 语法
// 获得文件名
const key = uuidv4();
const token = await getToken(key)
// 上传文件
const observable = qiniu.upload(file, key, token)
observable.subscribe({
next: (res) => {
// 进度展示
console.log(res, '进度')
},
error: (err) => {
console.log(err, '错误')
},
complete: (res) => {
console.log(res, '完成')
const url = cnd + res.key
insertFn(url, file.name, res.key)
}
})
}
},
},
};
// 销毁editor
useEffect(() => {
return () => {
if (editor == null) return;
editor.destroy();
setEditor(null);
};
}, [editor]);
return (
<>
<div style={{ border: '1px solid #ccc', zIndex: 100 }}>
<Toolbar
editor={editor}
defaultConfig={toolbarConfig}
mode='default'
style={{ borderBottom: '1px solid #ccc' }}
/>
<Editor
defaultConfig={editorConfig}
value={html}
onCreated={setEditor}
onChange={(editor) => setHtml(editor.getHtml())}
mode='default'
style={{ height: '500px', overflowY: 'hidden' }}
/>
</div>
{/* <div style={{ marginTop: '15px' }}>{html}</div> */}
</>
);
}
export default MyEditor;
具体解释:
1、使用wangEditor的customUpload功能,在customUpload里面,生成上传图片的key,然后通过服务端接口获取七牛的token。
// 获取七牛云上传 token
const getToken = async (key: string) => {
const res = await fetch(服务端接口地址);
const data = await res.json();
return data.token;
}
2、服务端生成token
import qiniu from 'qiniu';
import { NextRequest, NextResponse } from 'next/server';
export const GET = async (req: NextRequest) => {
// 获取key
const key = req.nextUrl.searchParams.get('key');
// 环境变量读取七牛配置
const bucket = process.env.QINIU_BUCKET;
const accessKey = process.env.QINIU_AK;
const secretKey = process.env.QINIU_SK;
// 创建鉴权对象
const mac = new qiniu.auth.digest.Mac(accessKey, secretKey);
const options = {
scope: bucket + ':' + key,
expires: 7200
};
const putPolicy = new qiniu.rs.PutPolicy(options);
const uploadToken=putPolicy.uploadToken(mac);
// 返回token
return NextResponse.json({
token: uploadToken,
});
}
七牛官方文档:developer.qiniu.com/kodo/1289/n…
3、使用七牛客户端工具上传
const observable = qiniu.upload(file, key, token)
observable.subscribe({
next: (res) => {
// 进度展示
console.log(res, '进度')
},
error: (err) => {
console.log(err, '错误')
},
complete: (res) => {
console.log(res, '完成')
const url = cnd + res.key
insertFn(url, file.name, res.key)
}
})
七牛官方文档:JavaScript SDK_SDK 下载_对象存储 - 七牛开发者中心
wangEditor文档:菜单配置 | wangEditor
最后,在客户端页面中可以直接使用当前的组件。