1. 引子
在使用markdown编写博客的时候,经常会需要插入图片。如果自己实现一个文件服务器,维护起来就会麻烦一点,如果有免费的文件服务使用,岂不是更好。本文介绍的就是如何实现一个附件上传功能,将图片上传到七牛云上。
2. 环境
在博客实现上,我使用的是Ant Design + React作为前端框架作为开发环境,开发结束后将其打包上传到阿里云上,并使用nginx对其进行部署;后端使用的是Spring Boot应用。
这里介绍七牛云,新用户赠送10个G的存储空间,而且还对资源提供CDN加速,简直就是白嫖党的福利,之前前端使用js+html架构的时候就用它来保存一些js,css插件,现在作为图床使用,嗯,真香。
3. 实现
3.1 前端
先介绍前端实现:
<Row>
<Col span={12}>
<Form.Item label="上传图片">
{
getFieldDecorator('upload-photo')(
<Upload
name= 'file'
action= 'http://upload.qiniu.com'
data={this.getUploadToken}
beforeUpload={this.beforeUpload.bind(this)}
onChange={this.handleUploadChange}
>
<Button>
Click to Upload
</Button>
</Upload>
)
}
</Form.Item>
</Col>
</Row>
首先引入antd的Upload组件,其中参数:
- action:就是上传的地址
- data:包含上传需要的token
- beforeUpload:上传前需要执行的操作
- onChange:监听事件,这里用来获取上传后返回的文件地址
上面涉及到的各类方法实现如下:
// 文件正式上传前执行的操作,返回true才会继续上传
beforeUpload(file) {
return true;
}
// 访问后端,获取请求上传凭证
fetchUploadToken = () => {
const { dispatch } = this.props;
dispatch({
type: 'blog/getUploadToken',
payload: {
},
callback: (res) => {
this.setState({
uploadToken: res.token,
fileKey: Date.now() + Math.floor(Math.random()*(999999-100000)+100000)+1
})
}
});
}
// 获取上传凭证
getUploadToken = () => {
return {
token : this.state.uploadToken,
key : this.state.fileKey
}
}
// 获取回传的文件地址
handleUploadChange = info => {
const { form } = this.props;
if(info.file.status === 'done'){
const imageKey = info.file.response.key
const uploadUrl = "http://cdn.yubuyun.com/"+imageKey;
form.setFieldsValue({cover:uploadUrl}); // 放到输入框中展示
}
}
其中fetchUploadToken方法在初始化中调用,从后台获取token
componentDidMount() {
this.fetchUploadToken();
}
这样后面上传文件时,就可以从state中拿到token了。
(关于后台如何实现,下面会讲到)
3.2 后端
首先添加依赖:
<dependency>
<groupId>com.qiniu</groupId>
<artifactId>qiniu-java-sdk</artifactId>
<version>[7.2.0,7.2.99]</version>
</dependency>
添加一个Controller:
@RestController
@CrossOrigin
@RequestMapping("/upload")
@Slf4j
public class UploadController {
private String accessKey = "..."; //此处手动打码
private String secretKey = "..."; //此处手动打码
private String bucket = "..."; //此处手动打码
@RequestMapping("/token/get")
public UploadTokenVO getToken() {
// 调用七牛云的接口获取token
Auth auth = Auth.create(accessKey,secretKey);
String upToken = auth.uploadToken(bucket);
UploadTokenVO uploadTokenVO = new UploadTokenVO();
uploadTokenVO.setToken(upToken);
return uploadTokenVO;
}
}
这里的accessKey,secretKey是从七牛云的个人中心中获取的。首先要开通开发者账号,开通后还要建一个桶,即上面的bucket,密钥可以在七牛云的个人中心页面上看到:4. 效果
前后端实现完后最终效果如下:
当点击上传按钮后,图片的保存地址就显示在输入框中了,然后就可以愉快的拿着这个地址放到markdown中使用了。