摘要:当时的方案是前端先调用微信的选择图片并上传,然后再从后端下载到服务器上。如果其值未设置或者设置成一个非法值,返回一个空文档和状态码。所以,之前返回不正常的这个问题,只要强行指定返回状态码,就可以正常收到返回的了并且也没有先前报错的问题了。
前段时间参与了一个H5项目,里边有个需求是用户上传图片。当时的方案是前端先调用微信的JSSDK选择图片并上传,然后再从后端下载到服务器上。然而用的时候发现客户端给的图片有大有小,但是由于用了微信的接口,图片在下载之前是没法控制的。后来在想能不能调用HTML5原生的文件上传接口,另外还可以配合阿里云的OSS对图片做进一步处理,所以就有了这篇文章。
1. HTML5原生上传其实之前也有想过用原生的,可手里的项目全是微信平台的H5,原生上传一直被告知有兼容性问题,所以这个方案一直是被搁置的;只是这次觉得用微信接口实在不爽才重新翻出来的,没想到意外发现手里的米4居然可以正常用。。好了闲话不说,上代码:
HTML部分主要就是那个input,至于下边那个div,主要是留着放图片预览用的。
文件填入FormData,然后POST上传,后端(用的PHP)简单写下接收就行。
(然后这里顺便想问下如果直接上传blob的话,PHP后端应该怎么写?有大神路过请不吝赐教~小弟这里先谢过了)
然后处理下权限啥的,就能跑啦。
2. 前端压缩(localResizeIMG)localResizeIMG 是个好插件,用法也很简单,把 GitHub 里的 dist 文件夹拖下来改个名(我改了个“localRZ”),然后直接引用 lrz.bundle.js 文件就行了:
localResizeIMG 的 文档 写的挺清楚的,哪里不明白的话可以过去看看。
3. 美化上传按钮原生的文件上传控件略丑,所以一般是要美化一下。
HTML:放一个 lable 上去,然后隐藏掉原有的 input:
这样看起来就舒服多了。
4. 对接OSS关于直传,阿里官方给了三种方案:
客户端 JavaScript 签名后直传;
客户端申请服务端签名,然后打包上传;
客户端申请服务端签名,打包上传OSS后回调服务端。
这里主要用的是第二种。
根据官方给的案例代码,首先要搞个签名用的PHP:
format(DateTime::ISO8601); $pos = strpos($expiration, "+"); $expiration = substr($expiration, 0, $pos); return $expiration."Z"; } //自行设置AccessKey和相应Bucket的外网域名 $id= "xxxxxxxxxxx"; $key= "yyyyyyyyyy"; $host = "http://zzzzzzz.oss-cn-xxxxxxxxx.aliyuncs.com/"; $now = time(); $expire = 10; //设置该policy超时时间是10s. 即这个policy过了这个有效时间,将不能访问 $end = $now + $expire; $expiration = gmt_iso8601($end); //文件大小范围.用户可以自己设置 $condition = array(0=>"content-length-range", 1=>0, 2=>1048576000); //设置用户上传指定的前缀 $dir = "test/"; //用户上传数据的位置匹配,这一步不是必须项,只是为了安全起见,防止用户通过policy上传到别人的目录 $start = array(0=>"starts-with", 1=>"$key", 2=>$dir); //设置bucket $bucket = array(0=>"eq", 1=>"$bucket", 2=>"gmei"); $conditions = array(0=>$bucket, 1=>$condition, 2=>$start); $arr = array("expiration"=>$expiration,"conditions"=>$conditions); //echo json_encode($arr); //return; $policy = json_encode($arr); $base64_policy = base64_encode($policy); $signature = base64_encode(hash_hmac("sha1", $base64_policy, $key, true)); $response = array( "accessid" => $id, "host" => $host, "policy" => $base64_policy, "signature" => $signature, "expire" => $end, "dir" => $dir."${filename}" ); echo json_encode($response);里边的东西填一下,然后保存在同目录下就行。然后改下HTML:
5. 遗留问题
OSS返回给客户端的XML没法正常解析6. 2016/8/31 补遗:
返回的XML是报错内容,但是不影响文件的正常上传(文件上传返回的是默认的204)。报错内容是(大意)“[AccessDenied]:The bucket you visit is not belong to you.”,查了下文档说原因是“子用户没有Bucket管理的权限(如getBucketAcl CreateBucket、deleteBucket setBucketReferer、 getBucketReferer等)”,调了半天的 RAM(访问控制)也没弄好,不知道是什么原因~上次留下几个问题,已经解决了,所以过来填坑。
其实这两个问题算是一个问题,在 PostObject 文档里,表单域里有个参数“success_action_status”,描述是“未指定success_action_redirect表单域时,该表单域指定了上传成功后返回给客户端的状态码。 接受值为200, 201, 204(默认)。 如果该域的值为200或者204,OSS返回一个空文档和相应的状态码。 如果该域的值设置为201,OSS返回一个XML文件和201状态码。 如果其值未设置或者设置成一个非法值,OSS返回一个空文档和204状态码。”所以,之前返回不正常的这个问题,只要强行指定返回201状态码,就可以正常收到返回的XML了(并且也没有先前报错的问题了)。
上代码:
最后总结了下,HTTP 一定要学好啊!!(于是哭着滚去看书了……)
【参考资料】
jQuery手册 - AJAX函数
理解DOMString、Document、FormData、Blob、File、ArrayBuffer数据类型
对象存储OSS - Web端直传实践:采用服务端签名后直传
对象存储OSS - API手册 - Post Object
对象存储OSS - API手册 - PostObject错误及排查
对象存储OSS - OSS控制台客户端Windows版
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/80195.html
摘要:当时的方案是前端先调用微信的选择图片并上传,然后再从后端下载到服务器上。如果其值未设置或者设置成一个非法值,返回一个空文档和状态码。所以,之前返回不正常的这个问题,只要强行指定返回状态码,就可以正常收到返回的了并且也没有先前报错的问题了。 前段时间参与了一个H5项目,里边有个需求是用户上传图片。当时的方案是前端先调用微信的JSSDK选择图片并上传,然后再从后端下载到服务器上。然而用的时...
摘要:一准备工作开通阿里云服务,从控制台上获取和。参考资料阿里云官方文档开始使用阿里云官方文档介绍如何在中快速使用访问服务微信公众号图片上传至阿里云前端图片直传试验如何基于和,快速搭建音视频文件上传服务声明转发请注明出处,谢谢 一、准备工作 1. 开通阿里云OSS服务,从控制台上获取AccessKeyId和AccessKeySecret。 2. 创建Bucket,并登录OSS控制台 3. 配...
摘要:前言为了减轻服务器压力,采用直传的方式,直接把资源图片,文件,视频等上传到阿里云服务器。这个是需要触发这个回调来通知服务器操作结果。服务器端同事调的,通过接口返回给前端的。这个就是签名,最关键的。的的使用如下结束这样就搞定了。 前言: 为了减轻服务器压力,采用web直传的方式,直接把资源(图片,文件,视频等)上传到阿里云oss服务器。但是阿里只提供 plupload.js 环境下的 d...
摘要:和数据直传到相比,以上方法有三个缺点上传慢。端向服务端请求签名,然后直接上传,不会对服务端产生压力,而且安全可靠。规定返回数据的格式,当前默认返回图片信息宽度高度,可获取更多数据。 背景 每个OSS的用户都会用到上传服务。Web端常见的上传方法是用户在浏览器或app端上传文件到应用服务器,然后应用服务器再把文件上传到OSS。 showImg(https://segmentfault.c...
阅读 2781·2021-09-23 11:44
阅读 1673·2021-09-13 10:24
阅读 2622·2021-09-08 09:36
阅读 1231·2019-08-30 15:54
阅读 2250·2019-08-30 13:54
阅读 3309·2019-08-30 10:57
阅读 1847·2019-08-29 18:43
阅读 3613·2019-08-29 15:10