H5选图预览到上传最佳实践

{"type":"doc","content":[{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"一 背景"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"在金融性质的App里,选择本地相册图片或者拍照,然后预览并且上传是一个典型的使用场景,比如常见的身份证信息上传。在最近接触的几家银行客户里,都反馈有类似的场景,并且在使用上都或多或少的遇到一些问题,最后找到我们,希望我们提供一些最佳实践。在这里分享下对应场景的一些优化解决方案。"}]},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"二 方案介绍"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"我们先介绍下各个银行的传统方案都是怎么做的,以及存在的问题。"}]},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"1. 选图方案"}]},{"type":"heading","attrs":{"align":null,"level":4},"content":[{"type":"text","text":"1.1 方案1:使用Android原生Webview"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"方案介绍:前端通过input标签,指定type=file,通过原生webview的支持实现选择文件。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"Android原生webView并不支持选择文件上传,需要外壳自己扩展WebChromeClient里的openFileChooser或者onShowFileChooser,然后去唤起系统选择文件弹框,选择文件会使用系统提供的组件或者其他支持的app,返回的uri有的直接是文件的url,有的是contentprovider的uri,需要统一处理一下返回uri格式。这种方案存在以下问题"}]},{"type":"numberedlist","attrs":{"start":"1","normalizeStart":1},"content":[{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":1,"align":null,"origin":null},"content":[{"type":"text","text":"外壳定制实现的逻辑较多,还需要对系统不同文件选择器返回的地址做兼容,容易有兼容性问题"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":2,"align":null,"origin":null},"content":[{"type":"text","text":"选择文件实现依赖系统的文件选择器,不同手机实现不一致,无法做到统一"}]}]}]},{"type":"heading","attrs":{"align":null,"level":4},"content":[{"type":"text","text":"1.2 方案2:使用mPaas的H5容器"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"如果业务使用了mPaas的H5容器后,虽然容器内已经内置了唤起文件选择器的一系列操作,但是还是一样存在系统文件选择器不可控的风险。比如如果业务希望选择的是一张图片,但是唤起后的效果可能是下面这个样子,很多客户也是无法接受的。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/f8/f835256fe17077db1bab7831963e0e9f.png","alt":null,"title":"input.png","style":[{"key":"width","value":"25%"},{"key":"bordertype","value":"none"}],"href":"","fromPaste":false,"pastePass":false}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":4},"content":[{"type":"text","text":"1.3 方案3:实现jsapi唤起Native自定义的选图页面"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"这种方案就是利用H5容器提供的自定义jsapi的能力,自定义一个选图的jsapi,然后前端去调用,去唤起Native自己实现的选图页面,最后结果通过base64的形式返回给前端做显示。这样就解决了前面提到系统选择文件不可控的问题。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"但是当这个方案上线后,还是遇到了一些问题,主要因为通过jsbridge只能返回json,所以图片数据是通过base64的形式返回的。但是因为有多选的场景,如果用户选择了多张图片后,返回的base64数据会特别大,导致在一些低端设备上有一些OOM的问题,同时大量base64转JSON的过程中,也会出现ANR。 所以也是不能上线的。"}]},{"type":"heading","attrs":{"align":null,"level":4},"content":[{"type":"text","text":"1.4 方案4:选图返回本地路径,webview拦截访问本地资源"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"为了解决前面提到的返回base64存在的稳定性问题,所以我们在选图的时候,是返回了一个本地的地址,然后Native模块拦截webview的资源访问,去本地拿到对应的图片返回给webview显示。比如选图后返回给webview的地址是:"},{"type":"link","attrs":{"href":"https://www.mPaas.com.cn/mpaas.jpg","title":null},"content":[{"type":"text","text":"https://www.mPaas.com.cn/mpaas.jpg"}]},{"type":"text","text":","},{"type":"link","attrs":{"href":"https://www.mPaas.com.cn/mpaas.jpg","title":null},"content":[{"type":"text","text":"www.mPaas.com.cn"}]},{"type":"text","text":"是我们自定义的一个域名,我们拦截这个特定自定义域名,然后去本地相册去找"},{"type":"link","attrs":{"href":"https://www.mPaas.com.cn/mpaas.jpg","title":null},"content":[{"type":"text","text":"mpaas.jpg"}]},{"type":"text","text":"对应的图片拦截返回。通过这样的一个转换逻辑,解决了base64传递的问题。"}]},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"2. 文件上传方案"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"通过以上的描述,我们对比了各种选图方案实现的优缺点,最后沉淀了最佳实践。选图实现了后,下一步就是上传。对于上传也经历了类似的方案演进。"}]},{"type":"heading","attrs":{"align":null,"level":4},"content":[{"type":"text","text":"2.1 方案1:使用RPC接口上传"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"对于使用了mPaas的用户,第一步想到的肯定是通过RPC接口实现文件的上传,但是在实际验证过程中,我们发现对于一些比较大的图片上传,RPC接口直接返回了403的报错,Http Transport error[413] : Request Entity Too Large]. 很明显是因为文件过大导致服务端挂掉了。主要因为RPC的定位是用做业务数据通道,一般建议的大小是200K以内,对于直接上传大文件的数据,会有稳定性风险,甚至因为这个把整个网关打挂。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/aa/aa11f83a0bba2b59711e9639414efca5.png","alt":"image.png","title":"image.png","style":null,"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":4},"content":[{"type":"text","text":"2.2 方案2:使用OSS方案上传"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"对于类似的文件上传场景,建议是直接使用OSS的方案进行上传,比如常见的阿里云OSS方案:"},{"type":"link","attrs":{"href":"https://help.aliyun.com/product/31815.html","title":null},"content":[{"type":"text","text":"https://help.aliyun.com/product/31815.html"}]},{"type":"text","text":"。OSS是专门为解决文件存储整条链路设计的一套方案,解决了文件上传的各种场景,用户可以集成对应的Android和iOS的SDK实现对本地文件的上传。"}]},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"三 总结"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"仅仅是一个选图上传预览这样一个场景,就可以有这么多不同的方案演进,没有最好的方案,只有最合适的方案。阿里云金融线专家服务团队为金融App提供最佳解决方案,欢迎大家了解。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}}]}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章