七牛是提供了 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
即可运行。