需求描述
想做一个可以上传图片到七牛服务器的个人空间里,不太喜欢通过后台来做这件事,比较想用js代码来完成,js直接本地将上传的图片传到七牛的个人空间中,需求就是这个样子。
讲解
网上很多博客实现都不完整,很多都试不出来,有些是直接就有问题的,很尴尬,自己就开始来做,首先要说明一点,
- 完全的JavaScript代码实现上述需求是不行的。
七牛的Github负责人也说了为了安全,他们并不想完全利用JavaScript来上传文件,但其实后台也没有多少代码量,我会贴后台代码出来,整个流程如下:
- 前端jsp代码
jsp代码提供引用包,点击按钮等。 - 前端js代码
这一块的js代码主要是初始化七牛sdk的Plupload控件的相关内容,代码会说明,还有一些点击事件、AJAX代码等。 - 后台java代码
后台代码主要是用来给js提供uptoken的,这一点很多博客没有讲到,当然他们代码也没有贴出来,本人会给大家讲解。
流程
代码
1、Jsp代码
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<div id="container">
<a class="btn btn-default btn-lg " id="pickfiles" href="#" >
<span>选择文件</span>
</a>
</div>
<input id="urlText" type="text" value=""></input> // 主要用来显示上传成功后的URl
</body>
<script type="text/javascript" src="https://cdn.staticfile.org/jquery/2.2.1/jquery.min.js"></script>
<script type="text/javascript" src="https://cdn.staticfile.org/plupload/2.1.9/moxie.js"></script>
<script type="text/javascript" src="https://cdn.staticfile.org/plupload/2.1.9/plupload.dev.js"></script>
<script type="text/javascript" src="https://cdn.staticfile.org/qiniu-js-sdk/1.0.14-beta/qiniu.min.js"></script>
<script type="text/javascript" src="JS/qiniu.js"></script>
<link rel="stylesheet" type="text/css" href="CSS/style_PublishGoods.css" />
<link rel="stylesheet" href="CSS/style.css" />
</html>
上述代码比较简单,主要是引用包,这个很重要,当然大家也可以去github上找官方文档,看这些包的说明,这些包并不是最新的,大家可以去了解最新的。
2、JavaScript代码
主要讲解qiniu.js脚本,下面是全部代码。
(function(w, d, u) {
var uploader;
function uploaderReady(token) {
// 引入Plupload 、qiniu.js后
uploader = Qiniu.uploader({
runtimes : 'html5,flash,html4', // 上传模式,依次退化
browse_button : 'pickfiles', // 上传选择的点选按钮,**必需**
uptoken : token, // 这里的token是AJAX得到的
// uptoken_url: '/token', //Ajax请求upToken的Url,**强烈建议设置**(服务端提供)
// uptoken: '', //若未指定uptoken_url,则必须指定 uptoken ,uptoken由其他程序生成
save_key: false, // save_key: true, // 默认 false。若在服务端生成uptoken的上传策略中指定了 `sava_key`,则开启,SDK会忽略对key的处理
domain : 'http://XXX.bkt.clouddn.com', // bucket 域名,下载资源时用到,这个可以到自己的七牛空间里找到具体url,**必需**
get_new_uptoken : false, // 设置上传文件的时候是否每次都重新获取新的token
container : 'container', // 上传区域DOM ID,默认是browser_button的父元素,
max_file_size : '4mb', // 最大文件体积限制
flash_swf_url : 'Moxie.swf', // 引入flash,相对路径
max_retries : 3, // 上传失败最大重试次数
dragdrop : true, // 开启可拖曳上传
drop_element : 'container', // 拖曳上传区域元素的ID,拖曳文件或文件夹后可触发上传
chunk_size : '4mb', // 分块上传时,每片的体积
auto_start : true, // 选择文件后自动上传,若关闭需要自己绑定事件触发上传
unique_names:false, // unique_names: true,
filters: { //对上传文件类型进行限制
mime_types : [
{ title : "Image files", extensions : "jpg,gif,png"}
],
max_file_size: "4mb",
prevent_duplicates: true
},
init : {
'FilesAdded' : function(up, files) {
plupload.each(files, function(file) {
// 文件添加进队列后,处理相关的事情
console.log(file.name);
});
},
'BeforeUpload' : function(up, file) {
// 每个文件上传前,处理相关的事情
},
'UploadProgress' : function(up, file) {
// 每个文件上传时,处理相关的事情
},
'FileUploaded' : function(up, file, info) {
// 每个文件上传成功后,处理相关的事情
// 其中 info 是文件上传成功后,服务端返回的json,形式如
// {
// "hash": "Fh8xVqod2MQ1mocfI4S4KpRL6D98",
// "key": "gogopher.jpg"
// }
// 参考http://developer.qiniu.com/docs/v6/api/overview/up/response/simple-response.html
var domain = up.getOption('domain');
var res = JSON.parse(info);
var sourceLink = domain + res.key; // 获取上传成功后的文件的Url
document.getElementById("urlText").value = sourceLink;// 将url展示到jsp input标签中
},
'Error' : function(up, err, errTip) {
// 上传出错时,处理相关的事情
},
'UploadComplete' : function() {
// 队列文件处理完毕后,处理相关的事情
},
'Key' : function(up, file) {
// 若想在前端对每个文件的key进行个性化处理,可以配置该函数
// 该配置必须要在 unique_names: false , save_key: false 时才生效
//key就是上传的文件路径
var key = "";
//获取年月日时分秒
var date = new Date();
var year = date.getFullYear();
var month = date.getMonth()+1;
var day = date.getDate();
var hour = date.getHours();
var minute = date.getMinutes();
var second = date.getSeconds();
key += '/Netease/' + year+'_'+month+'_'+day+'_'+hour+minute+second;
console.log("文件路径:"+file.name);
key += file.name;
return key
}
}
});
}
// domain 为七牛空间(bucket)对应的域名,选择某个空间后可以看到
// uploader 为一个plupload对象,继承了所有plupload的方法,参考http://plupload.com/docs
$(d).ready(function() {
var upToken;
var data={"name":"zhaonan"};
$.ajax({
cache : false,
async : false,
type : "POST",
dataType : "json",
url : "/ContentSales/Uptoken", // java 后台,获取upToken
data :JSON.stringify(data),
success : function(data) {
upToken = data.upToken;
uploaderReady(upToken);
},
error : function(XMLHttpRequest, textStatus, errorThrown) {
alert("textStatus="+textStatus+" errorThrown="+errorThrown);
alert("获取token失败");
}
});
});
document.getElementById('pickfiles').onclick = function() {
uploader.start();
};
})(window, document); // 这个脚本是随着页面加载开始运行的
特别说明:
domain :这个是从你的七牛空间中,选定某一个测试空间后的测试域名,当然这个域名是七牛给的,你也可以自己绑定自己想要的域名,具体如图所示:
上述就是一些准备工作。
3、Java代码
Java代码精简了一些,因为我是用了 SSM框架,很多代码是无用的,是框架必须的工作,本人就不贴了,主要给出获取Token的代码。
@RequestMapping(value = "/Uptoken", method = RequestMethod.POST)
@ResponseBody
public String getUptoken(String name,ModelMap model) {
System.out.println("uptoken方法:"+name);
// 获取七牛的uptoken
String upToken=FileUpUtil.getUpToken();
Map<String, String> map = new HashMap<String, String>();
JSONObject json;
map.put("upToken", upToken);
json = JSONObject.fromObject(map);
check_return=json.toString();
System.out.println("check_return="+check_return);
return check_return;
}
上述的getUpToken()方法是Service层的方法,,你不用框架的话,代码就比较简单。如下:
/** 基本配置-从七牛管理后台拿到,这两个后台获取
* 设置好账号的ACCESS_KEY和SECRET_KEY
*/
public String ACCESS_KEY = "9esKLdHh3wMjlD5QHt8_FkVa2XF42lgs8KVCOXXX";
public String SECRET_KEY = "pksDYci9-hs5D7FH6aF96_e_gNP9e_ul-GwH_XXX";
// 要上传的空间名--bucketname 也叫存储空间名,在七年里自己设置的
//对应要上传到七牛上 你的那个路径(自己建文件夹 注意设置公开)
public String bucketname = "neteasework";
@Override
public String getUpToken() {
// 密钥配置
System.out.println("初始化上传变量");
Auth auth = Auth.create(ACCESS_KEY, SECRET_KEY);
return auth.uploadToken(bucketname);
}
getUpToken()返回的就是Token。
Manven
这个也可以自己百度
<!-- 七牛云SDK -->
<dependency>
<groupId>com.qiniu</groupId>
<artifactId>qiniu-java-sdk</artifactId>
<version>7.2.11</version>
</dependency>