当前位置:   article > 正文

探索HTML5 Plus 拍照或者相册选择图片上传过程_html5 plus 实现手机app拍照或相册选择图片上传接口返回{"code":500,"msg"

html5 plus 实现手机app拍照或相册选择图片上传接口返回{"code":500,"msg":null,

起因:webApp中需要一个拍摄照片并上传服务器的功能

由于我正好使用Hbuilder在做webApp,所以自然想到了使用h5+中的调用摄像头功能

从此开始了踩坑之旅。。。

1.手机连接电脑问题

       如果你没有连接问题请跳过。

       手机通过数据线本来连接电脑好好的,突然就中断了,然后再咋也连不上电脑了,使用360手机助手连接也没用,而且我的手机设置和数据线及接口肯定没毛病,电脑重启一下就可以重连了,但总重启不是个事。

        然后我就想到通过数据线真机调试有问题,我试试用无线wifi真机调试看看行不行,借鉴了这篇文章:

https://www.cnblogs.com/weibanggang/p/9961742.html

下载了WiFi ADB工具,还真给无线连上了,然后再赶紧真机调试,发现可以连接了。结果运行app时才发现有大坑,我html引入的jq,bootstrap,图片啥的资源都找不到,没办法,还是想办法用usb连接电脑吧。

        查了半天,觉得唯一的可能就是我的usb驱动有问题,360手机助手提供的驱动可能兼容性不行,于是我下载了符合自己手机型号的usb驱动。因为我的是华为手机,只需要下载一个华为手机助手就可以了,下载地址:https://consumer.huawei.com/cn/support/hisuite/ 下载安装后连接手机就没问题了。(其他型号手机下载对应的驱动即可)

2.接口问题

由于官方文档写的不太清楚,理解有点费劲

5+调用相册接口官方文档:http://www.hcoder.net/tutorials/info_107.html

可知回调有三个参数:选择成功回调,选择失败回调,option配置参数。如果option配置了muitiple属性,则paths不再是一个路径,而是路径数组。

  1. plus.gallery.pick(function(path){
  2. console.log(path);
  3. $("#albumCoverImg").attr("src",path);//给我的img元素添加src,可以直接显示出图片
  4. });

返回的结果就是图片的物理路径

或者这么写:

  1. plus.gallery.pick(
  2. function(paths){
  3. console.log(paths)
  4. plus.nativeUI.showWaiting();
  5. },
  6. function(e){mui.toast('取消了选择');},
  7. {multiple:true,maximum:5}
  8. );

这样paths为一个数组,但貌似也只能选择一张图片,无法多选

调用摄像头接口:

  1. plus.camera.getCamera().captureImage(function(e){
  2. console.log("e is" + e);
  3. plus.io.resolveLocalFileSystemURL(e, function(entry) {
  4. var path = entry.toLocalURL();
  5. console.log(path);
  6. $("#albumCoverImg").attr("src",path) ;
  7. //upload(path);
  8. }, function(e) {
  9. mui.toast("读取拍照文件错误:" + e.message);
  10. });
  11. });

3.上传问题

      可以选择图片并返回图片的路径以后,上传图片又成了一个问题。

由于只能获取到图片的物理路径,js是无法只通过一个物理路径就上传这个文件的。因为浏览器的安全机制,所以得操作必须由用户点击来获取,只能使用h5中的input file才能获取到文件并保存到fileList中,且此数组为只读,外界获取不到,关于file可以看看这个https://blog.csdn.net/lianzhang861/article/details/80283120

       所以这就不能直接将图片放在form中上传了,只能通过5+的上传模块上传

5+ uploader模块官方文档:http://www.hcoder.net/tutorials/info_108.html

原理应该就是通过http 的post请求上传文件

  1. //服务端接口路径
  2. var server = ip+"package/uploadImg";
  3. // 上传文件
  4. function upload(path){
  5. console.log(server)
  6. var wt=plus.nativeUI.showWaiting();
  7. var task=plus.uploader.createUpload(server,
  8. {method:"POST"},
  9. function(t,status){ //上传完成
  10. if(status==200){
  11. var data=JSON.parse(t.responseText);
  12. alert("上传成功:"+t.responseText);
  13. wt.close(); //关闭等待提示按钮
  14. }else{
  15. alert("上传失败:"+status);
  16. wt.close();//关闭等待提示按钮
  17. }
  18. }
  19. );
  20. //添加其他参数
  21. task.addData("name","test");
  22. task.addFile(path,{key:"file"});
  23. task.start();
  24. }

代码就是上述所写,server为上传的服务端接口,如果上传成功,则回调的status会返回200,不成功或者接口参数有问题会返回400或者500。t.responseText返回服务端返回的结果,一般服务端会返回json,解析一下json就可以使用了。

传输其他文件时如果还想添加其他参数,用.addData(key,value),添加图片用.addFile(图片路径,{key:后端接收文件的名字}),

配合后端代码看会好理解,后端我用java接收的:

后端代码

  1. @RequestMapping(value = "/uploadImg", produces = "text/html;charset=utf-8")
  2. @ResponseBody
  3. public String uploadImg(@RequestParam Map<String, Object> paramMap,
  4. @RequestParam(value = "file") MultipartFile file,HttpServletRequest request) {
  5. Map<String, Object> map = new HashMap<>();
  6. String path=request.getSession().getServletContext().getRealPath("/")+"images\\";
  7. try {
  8. Map<String,String> name=uploadFile(path,file, request);
  9. map.put("success", true);
  10. map.put("code", "0");
  11. map.put("msg", "图片上传成功!");
  12. map.put("data","images/"+name.get("saveName"));
  13. } catch (Exception e) {
  14. e.printStackTrace();
  15. map.put("success", false);
  16. map.put("code", "-10");
  17. map.put("msg", "图片上传失败!");
  18. }
  19. return JSON.toJSONString(map);
  20. }
  21. public Map<String,String> uploadFile(String path,MultipartFile file, HttpServletRequest request) throws IOException {
  22. Map<String,String> result=new HashMap<String,String>();
  23. String fileName = file.getOriginalFilename();
  24. // String basePath=request.getSession().getServletContext().getRealPath("/");
  25. // path=basePath+path; //设置文件保存路径
  26. // File tempFile = new File(path, new Date().getTime() + String.valueOf(fileName));
  27. String fileType = fileName.substring(fileName.lastIndexOf(".") + 1, fileName.length()).toLowerCase();
  28. String saveName=String.valueOf((new Date()).getTime()).substring(8)+(int)((Math.random()*999+1))+'.'+fileType;
  29. //File tempFile = new File(basePath+path, String.valueOf(saveName));
  30. File tempFile = new File(path, String.valueOf(saveName));
  31. if (!tempFile.getParentFile().exists()) { //创建文件夹
  32. tempFile.getParentFile().mkdir();
  33. }
  34. if (!tempFile.exists()) {
  35. tempFile.createNewFile();
  36. }
  37. file.transferTo(tempFile);
  38. result.put("fileName",fileName);
  39. result.put("saveName",saveName);
  40. return result;
  41. }

用标准的MultipartFile接收即可。

返回图片的保存路径,用来配合其他表单一起提交。

前端完整代码示例:

  1. <!DOCTYPE HTML>
  2. <html>
  3. <head>
  4. <title>情报制作</title>
  5. <meta charset="utf-8" />
  6. <meta name="viewport" content="width=device-width, initial-scale=1" />
  7. <link rel="stylesheet" href="../css/mui.min.css">
  8. <link rel="stylesheet" href="../css/font-awesome-4.7.0/css/font-awesome.css" />
  9. <script src="../js/jquery-1.9.1.min.js" type="text/javascript" charset="utf-8"></script>
  10. </head>
  11. <body style="background-color: #f3f6f9;">
  12. <div style="height:500px;width:500px;overflow: hidden;">
  13. <img src="" alt="" id="albumCoverImg" style="width:100%;"/>
  14. </div>
  15. <button type="button" onclick="appendByGallery()">相册</button>
  16. <button type="button" onclick="appendByCamera()">拍摄</button>
  17. <script src="../js/mui.js"></script>
  18. <script type="text/javascript">
  19. //扩展API完成后执行的操作
  20. function plusReady(){
  21. //page.imgUp();
  22. }
  23. //弹出系统按钮选择框
  24. /*var page=null;
  25. page={
  26. imgUp:function(){
  27. var m=this;
  28. plus.nativeUI.actionSheet({cancel:"取消",buttons:[
  29. {title:"拍照"},
  30. {title:"从相册中选择"}
  31. ]}, function(e){//1 是拍照 2 从相册中选择
  32. switch(e.index){
  33. case 1:appendByCamera();break;
  34. case 2:appendByGallery();break;
  35. }
  36. });
  37. }
  38. } */
  39. // 拍照添加文件
  40. function appendByCamera(){
  41. plus.camera.getCamera().captureImage(function(e){
  42. console.log("e is" + e);
  43. plus.io.resolveLocalFileSystemURL(e, function(entry) {
  44. var path = entry.toLocalURL();
  45. $("#albumCoverImg").src = path;
  46. $("#albumCoverImg").attr("src",path) ;
  47. upload(path);
  48. }, function(e) {
  49. mui.toast("读取拍照文件错误:" + e.message);
  50. });
  51. });
  52. }
  53. // 从相册添加文件
  54. function appendByGallery(){
  55. plus.gallery.pick(function(path){
  56. console.log(path);
  57. $("#albumCoverImg").attr("src",path) ;
  58. upload(path);
  59. });
  60. }
  61. //服务端接口路径
  62. var server ='http://192.168.100.149:8085/packagePK/package/uploadImg';
  63. // 上传文件
  64. function upload(path){
  65. console.log(server)
  66. var wt=plus.nativeUI.showWaiting();
  67. var task=plus.uploader.createUpload(server,
  68. {method:"POST"},
  69. function(t,status){ //上传完成
  70. if(status==200){
  71. var data=JSON.parse(t.responseText);
  72. console.log(data.data);
  73. alert("上传成功:"+t.responseText);
  74. wt.close(); //关闭等待提示按钮
  75. }else{
  76. alert("上传失败:"+status);
  77. wt.close();//关闭等待提示按钮
  78. }
  79. }
  80. );
  81. //添加其他参数
  82. task.addData("name","test");
  83. task.addFile(path,{key:"file"});
  84. task.start();
  85. }
  86. //扩展API是否准备好,如果没有准备好则监听plusReady
  87. if(window.plus){
  88. plusReady();
  89. }else{
  90. document.addEventListener("plusready",plusReady,false);
  91. }
  92. </script>
  93. </body>
  94. </html>

 

 

 

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小小林熬夜学编程/article/detail/105018
推荐阅读
相关标签
  

闽ICP备14008679号