TP6 阿里云OSS(请求服务端签名,客户端直传)
插件合集
下载地址
http://gosspublic.alicdn.com/doc/oss-h5-upload-js-direct.zip?spm=a2c4g.11186623.2.11.4a383bd3mBCqlZ&file=oss-h5-upload-js-direct.zip
基类
<?php /** * Created by PhpStorm. * User: 张永峰 * Date: 2021/3/2 * Time: 9:55 * ━━━━━━━━━神兽出没━━━━━━━━━ * ┏┓ ┏┓+ + * ┏┛┻━━━┛┻┓ + + * ┃ ┃ * ┃ ━ ┃ ++ + + + * ████━████ ┃+ * ┃ ┃ + * ┃ ┻ ┃ * ┃ ┃ + + * ┗━┓ ┏━┛ * ┃ ┃ * ┃ ┃ + + + + * ┃ ┃ Code is far away from bug with the animal protecting * ┃ ┃ + 神兽保佑,代码无bug * ┃ ┃ * ┃ ┃ + * ┃ ┗━━━┓ + + * ┃ ┣┓ * ┃ ┏┛ * ┗┓┓┏━┳┓┏┛ + + + + * ┃┫┫ ┃┫┫ * ┗┻┛ ┗┻┛+ + + + * ━━━━━━━━━感觉萌萌哒━━━━━━━━━ */ namespace zyf; /** * @title 阿里云OSS存储签名 * Class Osss * @package zyf * @Date : 2021/3/2 * @Time : 9:55 */ class Osss { public function gmt_iso8601($time) { $expiration = date(DATE_ISO8601, $time); $pos = strpos($expiration, '+'); $expiration = substr($expiration, 0, $pos); return $expiration."Z"; } public function signedUrl() { $key = config('oss.main.AccessKeySecret'); $callbackUrl = config('oss.main.callbackUrl'); $dir = config('oss.main.dir'); $callback_param = array( 'callbackUrl' => $callbackUrl, 'callbackBody' => 'filename=${object}&size=${size}&mimeType=${mimeType}&height=${imageInfo.height}&width=${imageInfo.width}', 'callbackBodyType' => "application/x-www-form-urlencoded"); $callback_string = json_encode($callback_param); $base64_callback_body = base64_encode($callback_string); $now = time(); $expire = 3000; // 设置该policy超时时间是10s. 即这个policy过了这个有效时间,将不能访问。 $end = $now + $expire; $expiration = $this->gmt_iso8601($end); //最大文件大小.用户可以自己设置 $condition = array(0 => 'content-length-range', 1 => 0, 2 => 1048576000); $conditions[] = $condition; // 表示用户上传的数据,必须是以$dir开始,不然上传会失败,这一步不是必须项,只是为了安全起见,防止用户通过policy上传到别人的目录。 $start = array(0 => 'starts-with', 1 => '$key', 2 => $dir); $conditions[] = $start; $arr = array('expiration' => $expiration,'conditions' => $conditions); $policy = json_encode($arr); $base64_policy = base64_encode($policy); $string_to_sign = $base64_policy; $signature = base64_encode(hash_hmac('sha1', $string_to_sign, $key, true)); $response = array(); $response['accessid'] = config('oss.main.AccessKeyId'); $response['host'] = config('oss.main.host'); $response['policy'] = $base64_policy; $response['signature'] = $signature; $response['expire'] = $end; $response['callback'] = $base64_callback_body; $response['dir'] = $dir; // 这个参数是设置用户上传文件时指定的前缀。 return $response; } }
后台
// OSS public function oss() { if (IS_POST) { $oss = new \zyf\Osss(); return json($oss->signedUrl()); } return $this->render(); }
前端
<link rel="stylesheet" href="__COMMON__/oss/style.css"> <div class="layui-form-item"> <label class="layui-form-label">上传文件:</label> <div class="layui-input-block"> <h4>您所选择的文件列表:</h4> <div id="ossfile">你的浏览器不支持flash,Silverlight或者HTML5!</div> <br/> <div id="container"> <a id="selectfiles" href="javascript:void(0);" class='btn'>选择文件</a> <a id="postfiles" href="javascript:void(0);" class='btn'>开始上传</a> </div> <pre id="console"></pre> <p> </p> </div> </div> <script type="text/javascript" src="__COMMON__/oss/lib/plupload-2.1.2/js/plupload.full.min.js"></script> <script type="text/javascript" src="__COMMON__/oss/upload.js"></script>
JS
把下载的包中的uoload.js修改
修改send_request中的serverUrl
修改new plupload.Uploader中引入静态资源的路径
accessid = '' accesskey = '' host = '' policyBase64 = '' signature = '' callbackbody = '' filename = '' key = '' expire = 0 g_object_name = '' g_object_name_type = '' now = timestamp = Date.parse(new Date()) / 1000; function send_request() { var xmlhttp = null; if (window.XMLHttpRequest) { xmlhttp=new XMLHttpRequest(); } else if (window.ActiveXObject) { xmlhttp=new ActiveXObject("Microsoft.XMLHTTP"); } if (xmlhttp!=null) { // serverUrl是 用户获取 '签名和Policy' 等信息的应用服务器的URL,请将下面的IP和Port配置为您自己的真实信息。 // serverUrl = '666.com/common/Osss/signedUrl' // serverUrl = './php/get.php' xmlhttp.open("POST", '', false) xmlhttp.send(null) return xmlhttp.responseText } else { alert("Your browser does not support XMLHTTP."); } } // 生成随机文件名 function check_object_radio() { g_object_name_type = 'random_name'; } // 获取签名 function get_signature() { // 可以判断当前expire是否超过了当前时间, 如果超过了当前时间, 就重新取一下,3s 作为缓冲。 now = timestamp = Date.parse(new Date()) / 1000; if (expire < now + 3) { body = send_request() var obj = eval("(" + body + ")") host = obj['host'] policyBase64 = obj['policy'] accessid = obj['accessid'] signature = obj['signature'] expire = parseInt(obj['expire']) callbackbody = obj['callback'] key = obj['dir'] return true; } return false; } // 随机字符串 function random_string(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_suffix(filename) { pos = filename.lastIndexOf('.') suffix = '' if (pos != -1) { suffix = filename.substring(pos) } return suffix; } // 设置名称 function calculate_object_name(filename) { if (g_object_name_type == 'local_name') { g_object_name += "${filename}" } else if (g_object_name_type == 'random_name') { suffix = get_suffix(filename) g_object_name = key + random_string(10) + suffix } return '' } // 获取上传对象名称 function get_uploaded_object_name(filename) { if (g_object_name_type == 'local_name') { tmp_name = g_object_name tmp_name = tmp_name.replace("${filename}", filename); return tmp_name } else if (g_object_name_type == 'random_name') { return g_object_name } } // 设置上传参数 function set_upload_param(up, filename, ret) { if (ret == false) { ret = get_signature() } g_object_name = key; if (filename != '') { suffix = get_suffix(filename) calculate_object_name(filename) } new_multipart_params = { 'key' : g_object_name, 'policy': policyBase64, 'OSSAccessKeyId': accessid, 'success_action_status' : '200', //让服务端返回200,不然,默认会返回204 'callback' : callbackbody, 'signature': signature, }; up.setOption({ 'url': host, 'multipart_params': new_multipart_params }); up.start(); } var uploader = new plupload.Uploader({ runtimes: 'html5,flash,silverlight,html4', browse_button: 'selectfiles', container: document.getElementById('container'), flash_swf_url: '/static/common/oss/lib/plupload-2.1.2/js/Moxie.swf', silverlight_xap_url: '/static/common/oss/ossupload/lib/plupload-2.1.2/js/Moxie.xap', url: 'http://oss.aliyuncs.com', autostart: true, multi_selection: false, //是否支持多文件选择 init: { PostInit: function () { document.getElementById('postfiles').onclick = function () { set_upload_param(uploader, '', false); return false; }; }, FilesAdded: function (up, files) { plupload.each(files, function (file) { // 文件信息 document.getElementById('ossfile').innerHTML = '<input type="hidden" name="filename" value="' + file.name + '"><input type="hidden" name="filesize" value="' + plupload.formatSize(file.size) + '"><div class="onlyfile" data-id="' + file.id + '" id="' + file.id + '">' + file.name + ' (' + plupload.formatSize(file.size) + ')<b></b>' + '<div class="progress"><div class="progress-bar" style="width: 0%"></div></div>' + '</div>'; }); }, BeforeUpload: function (up, file) { check_object_radio(); set_upload_param(up, file.name, true); }, UploadProgress: function (up, file) { var fileid = $('.onlyfile').data('id') var d = document.getElementById(fileid); d.getElementsByTagName('b')[0].innerHTML = '<span class="upspeed">' + file.percent + "%</span>"; var prog = d.getElementsByTagName('div')[0]; var progBar = prog.getElementsByTagName('div')[0] progBar.style.width = 2 * file.percent + 'px'; progBar.setAttribute('aria-valuenow', file.percent); }, FileUploaded: function (up, file, info) { if (info.status == 200) { document.getElementById(file.id).getElementsByTagName('b')[0].innerHTML = 'upload to oss success, object name:' + get_uploaded_object_name(file.name) + ' 回调服务器返回的内容是:' + info.response; } else if (info.status == 203) { document.getElementById(file.id).getElementsByTagName('b')[0].innerHTML = '上传到OSS成功,但是oss访问用户设置的上传回调服务器失败,失败原因是:' + info.response; } else { document.getElementById(file.id).getElementsByTagName('b')[0].innerHTML = info.response; } }, Error: function (up, err) { if (err.code == -600) { document.getElementById('console').appendChild(document.createTextNode("\n选择的文件太大了,可以根据应用情况,在upload.js 设置一下上传的最大大小")); } else if (err.code == -601) { document.getElementById('console').appendChild(document.createTextNode("\n选择的文件后缀不对,可以根据应用情况,在upload.js进行设置可允许的上传文件类型")); } else if (err.code == -602) { document.getElementById('console').appendChild(document.createTextNode("\n这个文件已经上传过一遍了")); } else { document.getElementById('console').appendChild(document.createTextNode("\nError xml:" + err.response)); } } } }) uploader.init();