使用js直传oss阿里云存储文件,解决大文件上传服务器限制
- 每个OSS的用户都会用到上传服务。Web端常见的上传方法是用户在浏览器或App端上传文件到应用服务器,应用服务器再把文件上传到OSS。具体流程如下图所示。
客户短上传和数据直传到OSS相比,以上方法有三个缺点:
上传慢:用户数据需先上传到应用服务器,之后再上传到OSS。网络传输时间比直传到OSS多一倍。如果用户数据不通过应用服务器中转,而是直传到OSS,速度将大大提升。而且OSS采用BGP带宽,能保证各地各运营商之间的传输速度。
扩展性差:如果后续用户多了,应用服务器会成为瓶颈。
费用高:需要准备多台应用服务器。由于OSS上传流量是免费的,如果数据直传到OSS,不通过应用服务器,那么将能省下几台应用服务器。
上面可能废话有点多(阿里云官方解释),下面咱别写代码边解释!
以上oss直传js文件目录(后面可以下载!)
upload.js
accessid= '***';//阿里云oss accessid
accesskey= '***';//阿里云oss accesskey
host = 'https://***.oss-cn-beijing.aliyuncs.com';//Bucket 域名
g_dirname1 = ''
g_object_name1 = ''
g_object_name1_type = ''
now = timestamp = Date.parse(new Date()) / 1000;
var policyText1 = {
"expiration": "2040-12-01T12:00:00.000Z", //设置该Policy的失效时间,超过这个失效时间之后,就没有办法通过这个policy上传文件了
"conditions": [
["content-length-range", 0, 3048576000] // 设置上传文件的大小限制
]
};
var policyBase65 = Base64.encode(JSON.stringify(policyText1))
message1 = policyBase65
var bytes1 = Crypto.HMAC(Crypto.SHA1, message1, accesskey, { asBytes: true }) ;
var signature1 = Crypto.util.bytesToBase64(bytes1);
//设置成随机文件名
function check_object_radio1() {
var tt = document.getElementsByName('myradio1');
for (var i = 0; i < tt.length ; i++ )
{
if(tt[i].checked)
{
g_object_name1_type = tt[i].value;
break;
}
}
}
//设置上传目录
function get_dirname1()
{
dir = document.getElementById("dirname1").value;/前台做了一个输入框可以自己定义上传的目录
// dir ='';
if (dir != '' && dir.indexOf('/') != dir.length - 1)
{
dir = dir + '/'
}
g_dirname1 = dir
}
function random_string1(len) {
len = len || 32;
var chars = 'ABCDEFGHJKMNPQRSTWXYZabcdefhijkmnprstwxyz2345678';
var maxPos = chars.length;
var pwd = '';
for (i = 0; i < len; i++) {
pwd += chars.charAt(Math.floor(Math.random() * maxPos));
}
return pwd;
}
function get_suffix1(filename) {
pos = filename.lastIndexOf('.')
suffix = ''
if (pos != -1) {
suffix = filename.substring(pos)
}
return suffix;
}
function calculate_object_name1(filename)
{
if (g_object_name1_type == 'local_name')
{
g_object_name1 += "${filename}"
}
else if (g_object_name1_type == 'random_name')
{
suffix = get_suffix1(filename)
g_object_name1 = g_dirname1 + random_string(10) + suffix
}
return ''
}
function get_uploaded_object_name1(filename)
{
if (g_object_name1_type == 'local_name')
{
tmp_name = g_object_name1
tmp_name = tmp_name.replace("${filename}", filename);
return tmp_name
}
else if(g_object_name1_type == 'random_name')
{
return g_object_name1
}
}
function set_upload_param1(up, filename, ret)
{
g_object_name1 = g_dirname1;
if (filename != '') {
suffix = get_suffix1(filename)
calculate_object_name1(filename)
}
new_multipart_params = {
'key' : g_object_name1,//
'policy': policyBase65,
'OSSAccessKeyId': accessid,
'success_action_status' : '200', //让服务端返回200,不然,默认会返回204
'signature': signature1,
};
up.setOption({
'url': host,
'multipart_params': new_multipart_params
});
up.start();
}
var timer1,tryTime1,maxTry1=5,delay1=3000,num=0;
var uploader1 = new plupload.Uploader({//在文件里引入了一个 plupload前端上传插件
runtimes : 'html5,flash,silverlight,html4',
browse_button : 'selectfiles1',
//multi_selection: false,
container1: document.getElementById('container1'),
flash_swf_url : 'lib/plupload-2.1.2/js/Moxie.swf',
silverlight_xap_url : 'lib/plupload-2.1.2/js/Moxie.xap',
url : 'http://oss.aliyuncs.com',
init: {
PostInit: function() {
document.getElementById('ossfile1').innerHTML = '';
document.getElementById('postfiles1').onclick = function() {
set_upload_param1(uploader1, '', false);
return false;
};
},
FilesAdded: function(up, files) {//选择文件的信息
plupload.each(files, function(file) {
if(num==0){
document.getElementById('ossfile1').innerHTML += '<div id="' + file.id + '">' + file.name + ' (' + plupload.formatSize(file.size) + ')<b></b>'
+'<div class="progress"><div class="progress-bar" style="width:0%"></div></div>'
+'</div>';
num++;
}else{
return false;
}
});
},
BeforeUpload: function(up, file) {
check_object_radio1();
get_dirname1();
set_upload_param1(up, file.name, true);
},
UploadProgress: function(up, file) {
var d = document.getElementById(file.id);
d.getElementsByTagName('b')[0].innerHTML = '<span>' + file.percent + "%</span>";
var prog = d.getElementsByTagName('div')[0];
var progBar = prog.getElementsByTagName('div')[0]
progBar.style.width= 5*file.percent+'px';
progBar.setAttribute('aria-valuenow', file.percent);
},
FileUploaded: function(up, file, info) {
if (info.status == 200)
{
tryTime1 = 0;//注释的地方是前端页面的一个视频播放组件
// timer1 = setInterval(getDuration1, delay1);
// videoElem = document.getElementById("au");
// videoElem.innerHTML = '<source class="source" src="'+host+'/'+file.name+'" type="video/mp4">';
// videoElem.play();
$("#audioUrl").val(host+"/"+file.name+"");//返回的参数赋值到form之中
document.getElementById(file.id).getElementsByTagName('b')[0].innerHTML = 'upload to oss success, object name:' + get_uploaded_object_name1(file.name);
}
else
{
document.getElementById(file.id).getElementsByTagName('b')[0].innerHTML = info.response;
}
},
Error: function(up, err) {
document.getElementById('console1').appendChild(document.createTextNode("\nError xml:" + err.response));
}
}
});
function getDuration1() {
clearInterval(timer1);
var hour = parseInt((au.duration)/3600);
var minute = parseInt((au.duration%3600)/60);
var second = Math.ceil(au.duration%60);
$("#showByNones").show();
$("#lengthTime1").val(hour+":"+minute+":"+second);
var lengthTime = $("#lengthTime").val();
if (lengthTime == null || lengthTime == "") {
$("#showByNones2").show();
$("#lengthTime").val(hour+":"+minute+":"+second);
}
}
uploader1.init();
上传不仅仅上面一个文件还有lib文件夹里面的一些插件包
下面看下我自己写的前端页面
```html
div class="form-group">
<label class="col-sm-2 control-label">商品视频:</label>
<div class="col-sm-10">
<div style="display: none;">
<input type="radio" name="myradio1" value="local_name" checked=true/> 上传文件名字保持本地文件名字
<input type="radio" name="myradio1" value="random_name" /> 上传文件名字是随机文件名
上传到指定目录:<input type="text" id='dirname1' placeholder="如果不填,默认是上传到根目录" size=50>
</div>
<div>
<!-- <video height="240" object-fit="scale-down" controls="controls" muted="muted" loop id="au">-->
<!-- </video> 这个是html的视频组件和upload.js里面对应起来即可-->
<h4>您所选择的文件:</h4>
<div id="ossfile1" style="width: 200px;"></div>
<div id="container1">
<a id="selectfiles1" href="javascript:void(0);" class='btn'>选择文件</a>
<a id="postfiles1" href="javascript:void(0);" class='btn'>开始上传</a>
</div>
<!-- <pre id="console1"></pre> 里面是上传的回调信息-->
</div>
</div>
</div>
<div class="form-group" id="showByNones">
<label class="col-sm-2 control-label">视频网络地址:</label>
<div class="col-sm-10">
<input id="audioUrl" name="video" class="form-control"
type="text" value="{$data.video|default=''}" readonly="readonly">
</div>
</div>
<!-- 下面是引入的js -->
<script type="text/javascript" src="__PUBLIC__/js/oss/lib/crypto1/crypto/crypto.js"></script>
<script type="text/javascript" src="__PUBLIC__/js/oss/lib/crypto1/hmac/hmac.js"></script>
<script type="text/javascript" src="__PUBLIC__/js/oss/lib/crypto1/sha1/sha1.js"></script>
<script type="text/javascript" src="__PUBLIC__/js/oss/lib/base64.js"></script>
<script type="text/javascript" src="__PUBLIC__/js/oss/lib/plupload-2.1.2/js/plupload.full.min.js"></script>
<script type="text/javascript" charset="utf-8" src="__PUBLIC__/js/oss/upload1.js?v=3.6"></script>
上传效果如下:
下载文件直接傻瓜式操作!!!