七牛是提供了 NodeJS 的 SDK 的,这就为我们的使用带来了极大的方便。我们需要知道以下四个信息:
access_key
,secret_key
:可以在 https://portal.qiniu.com/user/key 上获取,如果没有则新建一对密钥。bucket
:对应的是空间名称,如果没有空间则需要新建一个空间。domain
:对应的是空间的域名,可以在 https://portal.qiniu.com/bucket/setting/domain?bucket=你的空间名称 中找到。
有了以上基本信息之后我们就可以在 ThinkJS 的基础上添加七牛图床了!首先我们需要新建一个 ThinkJS 项目,在命令行中执行:
//如果没有 thinkjs 命令则首先需要 npm install -g thinkjs
$ thinkjs new thinkjs-niu --es6
我们可以进入项目根目录安装依赖然后 start 一下,然后访问 http://localhost:8360 就会发现我们的 ThinkJS 项目已经可以正常访问啦!
$ cd thinkjs-niu
$ npm install
$ npm start
之前我们说到七牛有自己的 NodeJS SDK,所以下一步我们要先把 SDK 安装上,进入项目根目录后执行:
$ npm install qiniu --save
将我们在最开始获取到的四个信息配置到 config 里面,打开 src/home/config/config.js
并按照如下所示补充内容:
'use strict';
/**
* config
*/
export default {
//key: value
qiniu: {
access_key: '你的 access_key',
secret_key: '你的 secret_key',
bucket: '你的空间名称',
domain: '你的空间域名'
}
};
补充好后,继续打开 src/home/controller/index.js
并增加如下内容:
'use strict';
import Base from './base.js';
import qiniu from 'qiniu';
export default class extends Base {
/**
* index action
* @return {Promise} []
*/
indexAction(){
let qconfig = this.config('qiniu');
let putPolicy = new qiniu.rs.PutPolicy( qconfig.bucket );
qiniu.conf.ACCESS_KEY = qconfig.access_key;
qiniu.conf.SECRET_KEY = qconfig.secret_key;
this.assign({
uptoken: putPolicy.token(),
baseUrl: qconfig.domain
});
return this.display();
}
}
七牛上传图片需要三个关键的东西,一个是根据 key 生成的密钥 token,一个是文件的名称,最后一个当然是文件。通过 new qiniu.rs.PutPolicy(<bucket>).token()
方法我们就可以直接获取到生成的密钥了。这里不得不吐槽一下 qiniu.conf.ACCESS_KEY
和 qiniu.conf.SECRET_KEY
这样的设定,直接在模块上增加属性我也是醉了。最后我们把生成好的 uptoken
和定义的空间域名传入到模板中就 OK 了!
下面我们开始写我们的模板吧!模板的编写其实非常简单,清空 view/home/index_index.html
文件并添加如下代码:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>ThinkJS Qiniu Demo</title>
</head>
<body>
<form method="post" action="http://upload.qiniu.com/"
enctype="multipart/form-data">
<input name="key" type="hidden" value="">
<input name="token" type="hidden" value="<%=uptoken%>">
<input name="file" type="file" required/>
<button>OK</button>
</form>
</body>
</html>
保存后我们访问 http://localhost:8360 就可以进行测试了。选择图片并点击 OK 按钮后会提交文件到七牛的服务器上,七牛会返回类似一下内容的 JSON 字符串:
{"hash":"lqRwoZzfZ6_2QHand2ix6AITjOw_","key":""}
其中 key 就是我们七牛线上保存的文件名,将其与空间域名拼接后就能获取到文件的 URL 地址了。不过此时我们会发现 key 是空的,那是因为我们并没有上传 key,代表着文件名为空。解决办法是在表单提交之前获取 file 控件的值并拿到文件名。同时我们还会发现由于是表单上传所以页面会进行跳转,为了不进行跳转我们必须将表单提交替换为 AJAX 模拟表单提交。按照如下代码修改模板:
<form method="post" action="http://upload.qiniu.com/"
enctype="multipart/form-data" onsubmit="return send();">
<input name="key" type="hidden" value="">
<input name="token" type="hidden" value="<%=uptoken%>">
<input name="file" type="file" required/>
<button>OK</button>
</form>
<script>
/** 设置 key 值为文件名 **/
function setKey() {
var key = document.querySelector('input[name=key]');
var file = document.querySelector('input[name=file]');
var filename = file.value.match(/[^\/\\]+\.\w+$/);
if( !filename[0] ) {
return false;
}
key.value = filename[0];
return true;
}
/** 提交表单上传图片 **/
function send() {
var xhr = new XMLHttpRequest(), button = document.querySelector("button");
xhr.open("POST", "http://upload.qiniu.com", true);
xhr.onload = function() {
button.removeAttribute("disabled");
button.innerText = "OK";
var res = JSON.parse( xhr.responseText );
prompt('你上传的文件地址是:', "<%=baseUrl%>"+res.key);
}
button.setAttribute("disabled", "disabled");
button.innerText = "正在上传中...";
setKey();
xhr.send(new FormData(document.querySelector("form")));
return false;
}
</script>
动态设置文件名 key,增加 AJAX 表单提交,并在表单提交时修改按钮文字表示正在上传,上传结束之后弹窗提示用户文件的七牛地址。这样整个流程就完美了!本教程完整的示例代码可以从这里下载:百度云 | 云盘(提取码:4fd4)。下载解压 npm install
之后直接 npm start
即可运行。
雁过留声,人过留名。
七牛的服务很不错
公子,请教下Typecho怎么实现“引用”功能,引用评论的内容。不知道怎么调用
<blockquote>
。@徒然 你可以在后台开启允许评论使用 Markdown 语法,然后使用
的语法来写 blockquote,或者直接在评论设置“允许使用的HTML标签和属性”中添加
<blockquote>
的标签即可。@公子
啊!我表达有误,。。哈哈。我是不懂怎么实现那个功能 - -!像这个博客的回复旁边有个“引用”:http://www.woyigui.cn/guestbook/(不是广告!!)…
@徒然 那个呀,那个很简单的,你重写 replycomment 函数就好了,你可以参考我之前写的 At 插件,大同小异。
@公子好的,感谢!大致明白了!
js框架好多,学不过来了
终于搞定新主题tob上线,过来看看,博主好久没更新了呢?
好高端,小白表示看不懂。
网站标题适合做美女图片,JN站点。误点进来了。。
公子,该更新博客啦! 我们聊的那一期上线了, 可以发个博客哟 😃
不过,网站名字与这技术内容是不是不太搭呀?
挺不错,学习了。
您觉得处理URL的逻辑是加在 src/home/controller/index.js 比较好还是加在 src/home/logic/index.js 比较好
@solarhell 如果处理的 URL 需要后续处理的话还是放 controller 里头吧,如果只是用来做一些判断的就放 logic 里面吧。我觉得你可以先放在 controller 里面,最后如果你觉得它在 controller 里面有点显得多余,那就放 logic 里面吧。
有一点小小的问题 就是最后拼接出来的图片地址处理方面
要是没有在 src/home/config/config.js 在域名后加 “/” 可能需要再加一个判断 来给输出的拼接地址加上 “/”
@solarhell 嗯,是的。可以强制在拼接的时候加上
/
这样就不会有问题了,感谢提醒。写的很好,对于正在学习thinkjs的我很有帮助,谢谢博主!