这里文章都是从个人的github博客直接复制过来的,排版可能有点乱. 原始地址 http://benq.im/2015/04/28/hexomd-05/
 

上一篇我们实现了实时预览功能.

今天这篇要利用免费的七牛云存储服务来实现粘贴自动上传图片的功能.
不想看过程的朋友可以直接下载打包好的程序使用,使用之前记得配置七牛帐号.

文章的内容包含以下三点:

  1. 七牛云存储.
  2. clipboard-apis
  3. ajax文件上传

七牛云存储

系统设置

首先在系统设置里增加七牛空间设置部分,这里就简单的贴上代码,因为系统设置模块之前几篇了都讲过了.

system/model.js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
...
//默认设置
var defaultSystemData = {
//最后一次打开的文件
lastFile: null,
//编辑器样式
theme:'ambiance',
//预览窗口样式
preViewTheme:'github',
//预览代码块样式
preViewHighLightTheme:'default', /*七牛空间设置*/
accessKey:'',
secretKey:'',
//空间名称
bucketName:'test',
//空间访问地址
bucketHost:'7xit3a.com1.z0.glb.clouddn.com',
//过期时间,从设置之后多少小时过期.
deadline:1000
};

system.html

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
...
<div class="form-group">
<label>AccessKey</label>
<input class="form-control" name="accessKey" ng-model="systemSetting.accessKey"/>
</div>
<div class="form-group">
<label>SecretKey</label>
<input class="form-control" name="secretKey" ng-model="systemSetting.secretKey" type="text"/>
</div>
<div class="form-group">
<label>空间名</label>
<input class="form-control" name="bucketName" ng-model="systemSetting.bucketName" type="text"/>
</div>
<div class="form-group">
<label>空间域名</label>
<input class="form-control" name="bucketHost" ng-model="systemSetting.bucketHost" type="text"/>
</div>
<div class="form-group">
<label>过期时间</label>
<input name="deadline" class="form-control" ng-model="systemSetting.deadline" type="number"/>
</div>
...

增加了accesskey,secretkey,空间名,过期时间四个用于上传图片的字段. 其中accesskey, secretkey用于验证权限,空间名用于指定上传图片的存储空间,过期时间指定授权的过期时间. 这四个字段共同组成上传授权的Token,生成的方法如下:

安装七牛nodejs版sdk

1
npm install qiniu --save

system/model.js

1
2
3
4
5
6
7
8
9
10
11
12
...
//生成七牛存储空间token
system.qiniuKeygen = function(systemSetting){
var qiniu = require('../app/node_modules/qiniu');
qiniu.conf.ACCESS_KEY = systemSetting.accessKey;
qiniu.conf.SECRET_KEY = systemSetting.secretKey;
var putPolicy = new qiniu.rs.PutPolicy(systemSetting.bucketName);
putPolicy.expires = Math.round(new Date().getTime() / 1000) + systemSetting.deadline * 3600;
systemSetting.qiniutoken = putPolicy.token();
return systemSetting;
};
...

配置七牛帐号

首先得注册一个七牛帐号.

进入后台,新建一个空间,我这里取的空间名为blog,用于我博客的图片存储.

选择新建的空间,点击空间设置>域名设置,查看自动分配的域名

回到后台首页,点击账号设置,可以查看accessKey(AK)SecretKey(SK)

在刚做好的后台里配置好这几个字段

我把我空间的密钥遮住了,大家请填上自己的空间密钥

图片上传

图片的存储空间准备好了,现在来实现上传的功能.

初始化editor的时候传入七牛的token
studio/directive.js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
...
studio.directive('hmdEditor', function () {
return function ($scope, elem) {
var systemData = hmd.system.get();
hmd.editor.init({
el:elem[0],
theme:systemData.theme,
//七牛云存储授权
qiniuToken:hmd.system.qiniuKeygen(systemData).qiniutoken,
//空间的域名
bucketHost:systemData.bucketHost
},systemData.lastFile);
//保存最后一次打开的文件
hmd.editor.on('setFiled',function(filepath){
hmd.system.setLastFile(filepath);
});
...

studio/editor里实现图片上传功能

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
...
initQiniu:function(options){
this.qiniuToken = options.qiniuToken;
this.bucketHost = options.bucketHost;
//监听粘贴事件
$('.studio-wrap')[0].onpaste = this.uploadImage.bind(this);
},
uploadImage:function(ev){
var clipboardData, items, item;
if(!this.qiniuToken){
this.fire('error',{msg:'未设置七牛密钥,无法上传图片'});
}
//如果粘贴的是图片
else if (ev && (clipboardData = ev.clipboardData) && (items = clipboardData.items) &&
(item = items[0]) && item.kind == 'file' && item.type.match(/^image\//i)) {
//取图片数据
var blob = item.getAsFile();
//生成随机的图片名
var fileName = this.guid() + '.' + blob.type.split('/')[1];
//上传
this._qiniuUpload(blob, this.qiniuToken, fileName, function (blkRet) {
//生成markdown格式的图片地址
var img = '![](http://'+this.bucketHost+'/' + blkRet.key + ')';
//在光标处插入图片
this.cm.doc.replaceSelection(img);
}.bind(this));
return false;
}
},
//上传图片,参数为:图片2进制内容,七牛token,文件名,回调函数
_qiniuUpload:function (f, token, key,fn) {
var xhr = new XMLHttpRequest();
//创建表单
xhr.open('POST', 'http://up.qiniu.com', true);
var formData, startDate;
formData = new FormData();
if (key !== null && key !== undefined) formData.append('key', key);
formData.append('token', token);
formData.append('file', f);
var taking; xhr.onreadystatechange = function (response) {
//上传成功则执行回调
if (xhr.readyState == 4 && xhr.status == 200 && xhr.responseText) {
var blkRet = JSON.parse(xhr.responseText);
fn(blkRet);
} else if (xhr.status != 200 && xhr.responseText) {
if(xhr.status == 631){
hmd.editor.fire('error',{msg:'七牛空间不存在.'});
}
else{
hmd.editor.fire('error',{msg:'七牛设置错误.'});
}
}
};
startDate = new Date().getTime();
//提交数据
xhr.send(formData);
}
...

至此这个功能就完成了,随便截张图然后在编辑器里粘贴,编辑器就会自动生成图片引用地址:

这个功能较为简单,因此今天篇幅较小.

总结

粘贴上传图片的功能让我不用频繁的停下来上传图片,可以大大的提高用markdown写文章的效率.
目前功能还较为简单,不能指定图片名,不能分目录,大家可以根据自己的需求修改代码,完善功能.

接下来的计划:

  1. 自动更新.
  2. 云同步.
  3. 插件机制
  4. 表情插件.

附件

本篇程序打包,七牛云存储未设置好,请自行根据教程设置.
项目地址

自己动手开发更好用的markdown编辑器-05(粘贴上传图片)的更多相关文章

  1. 自己动手开发更好用的markdown编辑器-04(实时预览)

    这里文章都是从个人的github博客直接复制过来的,排版可能有点乱. 原始地址 http://benq.im/2015/04/25/hexomd-04/   程序打包   文章目录 1. 打开新窗口 ...

  2. 自己动手开发更好用的markdown编辑器-07(扩展语法)

    这里文章都是从个人的github博客直接复制过来的,排版可能有点乱. 原始地址 http://benq.im/2015/05/19/hexomd-07/   文章目录 1. 准备工作 2. 目录语法 ...

  3. 自己动手开发更好用的markdown编辑器-06(自动更新)

    这里文章都是从个人的github博客直接复制过来的,排版可能有点乱. 原始地址 http://benq.im/2015/05/12/hexomd-06/   文章目录 1. 自动更新方案 2. 实现 ...

  4. 自己动手制作更好用的markdown编辑器-01

    这里文章都是从个人的github博客直接复制过来的,排版可能有点乱. 原始地址  http://benq.im   文章目录 1. 简介 2. 项目结构 3. 程序主界面 4. 拖动窗口 5. app ...

  5. 自己动手制作更好用的markdown编辑器-03

    这里文章都是从个人的github博客直接复制过来的,排版可能有点乱. 原始地址 http://benq.im/2015/04/24/hexomd-03/ 文章目录 1. 系统模块 2. 记录上次打开的 ...

  6. 自己动手制作更好用的markdown编辑器-02

    这里文章都是从个人的github博客直接复制过来的,排版可能有点乱. 原始地址 http://benq.im 文章目录 1. 工具条 1.1. 样式 1.2. 工具条截图 2. 状态栏消息 3. 文件 ...

  7. 任由文字肆意流淌,更自由的开源 Markdown 编辑器

    对于创作平台来说内容编辑器是十分重要的功能,强大的编辑器可以让创作者专注于创作"笔"下生花.而最好取悦程序员创作者的方法之一就是支持 Markdown 写作,因为大多数程序员都是用 ...

  8. Markdown编辑器开发记录(二):Markdown编辑器的使用与开发入门

    Markdown编辑器的使用与开发入门 在部门做技术分享的时候简单整理了一下手里的资料 1 是什么 1.1 Markdown是一种轻量级标记语言 Markdown是一种轻量级标记语言,创始人为约翰·格 ...

  9. Markdown编辑器开发记录(一):开发的初衷和初期踩的坑

    先说下选择Markdown编辑器的原因,我们进行平台开发,需要很多的操作手册和API文档,要在网站中展示出来就需要是HTML格式的文件,但是由于内容很多,不可能全部由技术人员进行文档的编写,如果是只有 ...

随机推荐

  1. 差分+树状数组 线段树【P2357】 守墓人

    题目描述-->p2357 守墓人 敲了一遍线段树,水过. 树状数组分析 主要思路: 差分 简单介绍一下差分(详细概念太麻烦,看下面. 给定一个数组 7 8 6 5 1 8 18 20 35 // ...

  2. 21、Django实战第21天:课程章节信息

    在课程详情页中,点击"开始学习",就进入到这课程章节信息,这里面包含了两个页面:"章节"和评论 1.把course-video.html(章节).course- ...

  3. 在scientificlinux7(centos7)中搭建apache+php本地服务器

    首先安装httpd(apache), 开始没有注意,以为可以这样安装 yum install apache 结果不对,搜索下 yum -qvh apache 命令是错的,在来 yum search a ...

  4. 【线性基】【贪心】【独立环】bzoj2115 [Wc2011] Xor

    网上到处都是题解,自己画个图也很好理解.虽然环的个数很多,但是都可以通过独立环之间异或出来,不用管. 独立环求法:生成树之后,每次向图里添加非树边(u,v),则这个独立环的异或和为sum[u]^sum ...

  5. React Native学习之DeviceEventEmitter传值

     使用DeviceEventEmitter前需添加 import { AppRegistry, StyleSheet, Text, View, DeviceEventEmitter } form 'r ...

  6. 关于ArrayList的一些源码分析

    集合是Java中非常重要而且基础的内容,因为任何数据必不可少的就是该数据是如何存储的,集合的作用就是以一定的方式组织.存储数据.这里写的集合,一部分是比较常见的.一部分是不常用但是我个人平时见到过的, ...

  7. java基础之:java注解

    一:元注解 元注解的作用就是负责注解其他注解.Java5.0定义了4个标准的meta-annotation类型,它们被用来提供对其它 annotation类型作说明.Java5.0定义的元注解: 1. ...

  8. dot language 学习笔记

    dot language 学习笔记 UP | HOME   dot language 学习笔记 Table of Contents 1 dot 语言简介 2 基本语法 2.1 常用图形 2.2 常用线 ...

  9. 安装Node.js、npm和环境变量的配置

    由于Node.js平台是在后端运行JavaScript代码,所以,必须首先在本机安装Node环境. 一.安装Node.js 首先,从Node.js官网下载对应平台的安装程序,网速慢的童鞋请移步国内镜像 ...

  10. git 出现502错误后用depth一步一步来

    公司有个项目的git仓库,因为一些二进制文件也放在里面,版本迭代后,整个仓库特别大,有好几G. 直接git clone是不行的,会报这样的错误: error: RPC failed; HTTP 502 ...