首页
随笔
生活
MAC
技术
游戏
随言碎语
阿里云OSS集成百度webuploader记录
2023-10-21
yu.shi
449
近期有一个项目用到了阿里云的OSS来存储文件,这里记录一下其中解决问题的过程。 # 开通OSS 要到阿里云控制台中开通,创建一个新的Bucket来作为文件存储的模块 # 申请key和secret 这里找了很久,要在[RAM访问控制](https://ram.console.aliyun.com/manage/ak "RAM访问控制")中申请 # 开通跨域 没有跨域没办法上传,在“数据安全”->“跨域设置”中,添加一条规则 # 无法直接预览? 注意读写模式不要设置为私有,私有的预览很麻烦,只能下载不能直接外网查看,要在“概览”->“读写权限”中修改为“公共读” ------ 以上为前期准备,设置好之后就可以开始coding部分 ------ # 前端直传模式 比较合适的用法还是前端直传,不用走后台服务器,目的就是让应用服务器不需要那么大的承载量,文件直接走OSS。 # 前端业务 用的是百度的webuploader,ajax上传,手机端、web端都非常好用,这里调整改动非常小,只有三个部分 1. 实例化中的上传文件接口 ``` var uploader = WebUploader.create({ server: '', // 这里要设置为概览中 外网域名的 Bucket 域名 }) ``` 2. uploadBeforeSend上传前在参数中添加签名 签名从应用后台获得,避免key和secret暴露在页面里。整体流程即:前端上传前请求签名->上传时带上签名->上传后预览文件 ``` uploader.on('uploadBeforeSend', function (obj, data, headers) { console.log(obj) // expire 过期才去获取下面的信息 $.ajax({ type: 'POST', url: "{:U('Public/getOSS')}", data: { file: obj.file.name, id: '{$info.id}' }, // 这里data用来向获取OSS签名的方法里传输一些参数 timeout: 10000, dataType: "JSON", success: function (obj2) { // console.log(obj2) UPLOAD_FILE_NAME = data = $.extend(data, { 'key': obj2.dir + 'video/' + obj2.title,// 这里在后台处理好 'policy': obj2.policy, 'OSSAccessKeyId': obj2.accessid, 'success_action_status': '200', // 让服务端返回200,不然,默认会返回204 //'callback' : obj2.callback, 'signature': obj2.signature, }) UPLOAD_FILE_PATH = data.key }, error: function (XMLHttpRequest, textStatus, errorThrown) { alert("ajax error"); }, async: false }) headers['Access-Control-Allow-Origin'] = "*"; }) ``` 上面的代码里有几个注意的点: - 前端直传,暂时没找到方法获取回调,回调过来的只有200,其余都没有,因此需要自行拼接文件名,如果仅靠用户上传的文件名,同文件名会自动覆盖掉,因此在ajax中向后台传了data,此data用来在后台拼装出文件名 - callback是注释掉的,OSS的callback是OSS方向应用服务器后台提交一个回调请求,无法传输到前台地址,显得鸡肋(也可能是我不会用),因此就去掉了 3. 上传成功后的预览 由于无法获得回调,因此要在全局定义一个文件路径,此路径上传时就已经拼装好,上传后就可以直接通过HOST+路径来查看到上传的文件实现预览 ``` uploader.on('uploadSuccess', function (file, response) { // console.log(UPLOAD_FILE_PATH) // 全局定义的路径,注意要拼装HOST,这里没拼装上 var src = UPLOAD_FILE_PATH $('#videoPlay').attr('src', src) }); ``` 其余的都和webuploader使用一模一样,就需要变这几个地方就可以 # 后端业务 后端就非常简单了,只要获取签名传给前台即可,笔者还用的tp3.2 首先是在config里配置好相关的参数 ``` 'ALI_OSS' => array( 'KEY' => 'XXX', // key 'SECRET' => 'XXXX', // 密钥 'HOST' => 'http://xxxxxxx.oss-cn-beijing.aliyuncs.com', // 域名 'DIR_PRE' => 'xxxxx/', // 上传路径,注意要斜杠结尾 ), ``` 再是公共的function.php里,给出签名算法 ``` function gmt_iso8601($time) { return str_replace('+00:00', '.000Z', gmdate('c', $time)); } /** * 获取阿里云OSS签名 * @return array */ function getAliYunSignature() { $config = C('ALI_OSS'); $id = $config['KEY']; // 请填写您的AccessKeyId。 $key = $config['SECRET']; // 请填写您的AccessKeySecret。 // $host的格式为 bucketname.endpoint,请替换为您的真实信息。 $host = $config['HOST']; // $callbackUrl为上传回调服务器的URL,请将下面的IP和Port配置为您自己的真实URL信息。 // $callbackUrl = 'http://88.88.88.88:8888/aliyun-oss-appserver-php/php/callback.php'; $dir = $config['DIR_PRE']; // 用户上传文件时指定的前缀。 // $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 = 10; // 设置该policy超时时间是10s. 即这个policy过了这个有效时间,将不能访问。 $end = $now + $expire; $expiration = 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'] = $id; $response['host'] = $host; $response['policy'] = $base64_policy; $response['signature'] = $signature; $response['expire'] = $end; // $response['callback'] = $base64_callback_body; $response['dir'] = $dir; // 这个参数是设置用户上传文件时指定的前缀。 return $response; } ``` 最后是控制器里,给出获取签名和处理文件名的方法 ``` /** * 获取上传OSS信息 * 注意要把OSS设置为公共读 * @return void */ public function getOSS() { // 获取文件名并生成OSS用文件名 $fileName = I('file', '', 'string'); $id = I('id', '', 'string'); // 查code // 我这里是业务相关,用业务的code来命名 $code = M('sign')->where(array('id' => $id))->getField('code'); $pathInfo = pathinfo($fileName); $ext = $pathInfo['extension']; // 加时间戳后缀,避免覆盖掉 $newFileName = $code . '_' . date('YmdHis') . '.' . $ext; $res = getAliYunSignature(); $res['title'] = $newFileName; $this->ajaxReturn($res); } ``` # 删除 待做
0
yu.shi
爱生活,爱游戏,爱coding,爱工作
139658
总访问量
47
站内文章数
1730
博客开设天数
随笔点击排行
1
剧本杀《千千晚星》
(1937)
2
无公网IP+ZeroTier+...
(1912)
3
关于梦想
(1486)
4
P5R攻略两篇
(1445)
5
树莓派制作电子相册
(1381)
标签
生活
PHP
前端
公考
PS4
魂系列
树莓派
友情连接
PSN
兄弟影视
WEUI
WEUI.JS
音乐解密
无损音乐