最近在项目开发中,有一个在微信WEB项目中上传图片的需求,一开始使用了传统的<input type="file">的方式去实现,但是后面发现在使用这种传统模式时会由于手机系统的差异而导致一系列的问题,后改用微信JSSDK的方式来实现,做的过程中也遇到了一些小坑,把经验贴出来给大家分享一下,让大家少走点弯路。

  总的来说,利用JSSDK来实现该功能一共分为四步。

  1. 调用wx.config(),初始化jssdk的配置,并在jsApiList中配置上传图片需要的四个api('chooseImage','previewImage','uploadImage','downloadImage')

wx.config({
debug : false,
appId : data.appId,
timestamp : data.timestamp,
nonceStr : data.nonceStr,
signature : data.signature,
jsApiList : [
'chooseImage',
'previewImage',
'uploadImage',
'downloadImage'
]
});

  2.点击图片时,调用wx.chooseImage(),让用户去选择图片或拍照

 function wxChooseImage() {
wx.chooseImage({
count: 1,
sizeType: ['original', 'compressed'],
sourceType: ['album', 'camera'],
success: function (data) {
var localIds = data.localIds[0].toString();
wxuploadImage(localIds);
}
});
}

  3.选择完图片后调用wx.chooseImage(),将图片上传到微信服务器

 function wxuploadImage(e) {
layer.load(1);
wx.uploadImage({
localId: e,
isShowProgressTips: 0,
success: function (res) {
fileUpload(res.serverId);
}
});
}

  4.利用mediaId将图片从微信服务器下载到本地或项目的图片服务器路径下,并展示图片

 function fileUpload(mediaId) {
$.ajax({
url: KY.basePath + "/image/upload.htm",
dataType: 'json',
data: {
"mi": mediaId
},
type: "post",
success: function(result) {
$("#imghead").attr("src", KY.imageServer + result.path);
}
});
}

附:服务端从微信服务器下载图片的代码,在此处,我是将图片从微信服务器下载后调用另一个专门负责上传图片的项目去进行的上传操作,大家也可以在第73行代码获取到流之后下载到本地。

 package com.hyde.carelink2.wechat.utils;

 import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map; import org.apache.commons.httpclient.NameValuePair;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.mime.content.ByteArrayBody;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import com.fasterxml.jackson.databind.ObjectMapper;
import com.hyde.carelink2.wechat.domain.upload.UploadImagResponse;
import com.hyde.carelink2.wechat.service.wechat.WechatServerCenter;
import com.hyde.common.StatusCode;
import com.hyde.common.enums.ImageToken;
import com.hyde.common.enums.ProjectType;
import com.hyde.common.utils.HttpUtil;
import com.hyde.config.enums.ConfigType;
import com.hyde.config.impl.CommonConfig; /**
* @author WangHuijie
*/
public class DownloadImageUtil { private final static Logger LOGGER = LoggerFactory.getLogger(DownloadImageUtil.class); private static ObjectMapper objectMapper = new ObjectMapper(); /**
* 从微信服务器获取媒体文件
*
* @param param
* @param mediaId
* @param request
* @return
*/
public static Map<String, String> getImageFromWechat(String mediaId) { Map<String, String> map = new HashMap<String, String>();
String accessToken = ""; // 接口访问凭证
try {
accessToken = WechatServerCenter.getAccessToken();
} catch (Exception e) {
LOGGER.error(e.getMessage(), e);
}
String filePath = "";
// 拼接请求地址
String requestUrl = "http://file.api.weixin.qq.com/cgi-bin/media/get?access_token=" + accessToken + "&media_id=" + mediaId;
try {
URL url = new URL(requestUrl);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setDoInput(true);
conn.setDoOutput(true);
conn.setRequestMethod("GET");
conn.setRequestProperty("Content-Type", "application/form-data");
InputStream inputStream = conn.getInputStream(); if (inputStream != null) {
HttpURLConnection conn1 = (HttpURLConnection) url.openConnection();
conn1.setDoInput(true);
conn1.setDoOutput(true);
conn1.setRequestMethod("GET");
conn1.setRequestProperty("Content-Type", "application/form-data");
InputStream inputStream1 = conn1.getInputStream(); if (inputStream1 != null) {
// 根据内容类型获取扩展名
String contentType = conn1.getHeaderField("Content-Type");
String expandName = getFileexpandedName(contentType);
String fileName = mediaId + expandName;
filePath = getUploadServerPath(inputStream1, contentType, fileName);
map.put("path", filePath);
map.put("code", String.valueOf(StatusCode.SUCCESS.getIndex()));
map.put("msg", StatusCode.SUCCESS.getMessage());
} else {
map.put("code", String.valueOf(StatusCode.ERROR.getIndex()));
map.put("msg", StatusCode.ERROR.getMessage());
}
} else {
map.put("code", String.valueOf(StatusCode.ERROR.getIndex()));
map.put("msg", StatusCode.ERROR.getMessage());
}
inputStream.close();
conn.disconnect();
} catch (Exception e) {
LOGGER.error(e.getMessage(), e);
}
return map;
} public static String getUploadServerPath(InputStream inputStream, String contentType, String fileName) { String filePath = null;
byte[] bytes = new byte[0];
try {
bytes = toByteArray(inputStream);
} catch (IOException e) {
LOGGER.error(e.getMessage(), e);
}
String token = "DM5344d93e19c41adb5e0f5531bdd0336";
ProjectType projectType = ProjectType.CARELINK2;
ImageToken type = ImageToken.CARELINK2_USER_PORTRAIT;
UploadImagResponse response = uploadImage(bytes, token, contentType, fileName, projectType, type);
if (response != null) {
filePath = response.getFilePath();
}
return filePath;
} /**
* 执行文件上传到图片服务器
*
* @param bytes
* @param token
* @param contentType
* @param fileName
* @param param
* @return
*/
protected static UploadImagResponse uploadImage(byte[] bytes, String token, String contentType, String fileName, ProjectType projectType, ImageToken type) { try {
ByteArrayBody arrayBody = new ByteArrayBody(bytes, ContentType.create(contentType), fileName);
List<NameValuePair> pairs = new ArrayList<NameValuePair>();
NameValuePair projectTypePair = new NameValuePair("p", String.valueOf(projectType.getIndex()));
pairs.add(projectTypePair);
NameValuePair typePair = new NameValuePair("type", String.valueOf(type.getIndex()));
pairs.add(typePair);
String url = CommonConfig.getConfig(ConfigType.UPLOAD_SERVICE_URL, String.class);
String status = HttpUtil.postFile(url, arrayBody, token, pairs);
UploadImagResponse response = objectMapper.readValue(status, UploadImagResponse.class);
return response;
} catch (Exception e) {
LOGGER.error(e.getMessage(), e);
}
return null;
} /**
* 将输入流转为byte数组
* @param input
* @return
* @throws IOException
*/
public static byte[] toByteArray(InputStream input) throws IOException {
ByteArrayOutputStream output = new ByteArrayOutputStream();
byte[] buffer = new byte[4096];
int n = 0;
while (-1 != (n = input.read(buffer))) {
output.write(buffer, 0, n);
}
return output.toByteArray();
} /**
* 根据内容类型判断文件扩展名
* @param contentType 内容类型
* @return
*/
public static String getFileexpandedName(String contentType) { String fileEndWitsh = "";
if ("image/jpeg".equals(contentType)) {
fileEndWitsh = ".jpg";
} else if ("audio/mpeg".equals(contentType)) {
fileEndWitsh = ".mp3";
} else if ("audio/amr".equals(contentType)) {
fileEndWitsh = ".amr";
} else if ("video/mp4".equals(contentType)) {
fileEndWitsh = ".mp4";
} else if ("video/mpeg4".equals(contentType)) {
fileEndWitsh = ".mp4";
}
return fileEndWitsh;
} }

微信JS-SDK实现上传图片功能的更多相关文章

  1. 实战微信JS SDK开发:贺卡制作与播放(1)

    前段时间忙于CanTK 2.0的开发,所以博客一直没有更新.CanTK 2.0主要增强了游戏和富媒体的开发,现在编码和测试基本完成了,等文档完成了再正式发布,里面有不少激动人心的功能,等发布时再一一细 ...

  2. 微信JS SDK接入的几点注意事项

    微信JS SDK接入,主要可以先参考官网说明文档,总结起来有几个步骤: 1.绑定域名:先登录微信公众平台进入“公众号设置”的“功能设置”里填写“JS接口安全域名”.备注:登录后可在“开发者中心”查看对 ...

  3. 微信js sdk上传多张图片

    微信js sdk上传多张图片,微信上传多张图片 该案例已tp3.2商城为例 直接上代码: php代码: public function ind(){ $appid="111111111111 ...

  4. 微信js SDK接口

    微信JS-SDK说明文档 http://mp.weixin.qq.com/wiki/7/aaa137b55fb2e0456bf8dd9148dd613f.html 一.微信登录功能 在进行微信OAut ...

  5. 微信JS SDK配置授权,实现分享接口

    微信开放的JS-SDK面向网页开发者提供了基于微信内的网页开发工具包,最直接的好处就是我们可以使用微信分享.扫一扫.卡券.支付等微信特有的能力.7月份的时候,因为这个分享的证书获取问题深深的栽了一坑, ...

  6. 微信开发(2):微信js sdk分享朋友圈,朋友,获取config接口注入权限验证(转)

    进行微信开发已经一阵子了,从最初的什么也不懂,到微信授权登录,分享,更改底部菜单,素材管理,等. 今天记录一下微信jssdk 的分享给朋友的功能,获取config接口注入. 官方文档走一下简单说:四步 ...

  7. 调用微信js sdk

    场景:需要调用微信获取当前位置的借口. 途径:查看微信 https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421141115 .后 ...

  8. 微信JS SDK使用权限签名算法

    jsapi_ticket 生成签名之前必须先了解一下jsapi_ticket,jsapi_ticket是公众号用于调用微信JS接口的临时票据.正常情况下,jsapi_ticket的有效期为7200秒, ...

  9. 微信js sdk分享开发摘记java版

    绑定域名和引入js的就不说了 废话不说直接上代码 public void share(HttpServletRequest request) throws Exception { StringBuff ...

  10. 微信JS SDK Demo 官方案例[转]

    摘要: 微信JS-SDK是微信公众平台面向网页开发者提供的基于微信内的网页开发工具包. 通过使用微信JS-SDK,网页开发者可借助微信高效地使用拍照.选图.语音.位置等手机系统的能力,同时可以直接使用 ...

随机推荐

  1. 使用Discuz!自带参数防御CC攻击以及原理

    CC攻击确实是很蛋疼的一种攻击方式,Discuz!的配置文件中已经有了一个自带的减缓CC攻击的参数,在配置文件config.inc.php中: $attackevasive = 0;  // 论坛防御 ...

  2. 在线调整InnoDB Buffer Pool Size

    InnoDB Buffer Pool主要是用来缓存数据表和索引数据的内存区域,它的默认值为134217728字节(128MB).最大值取决于CPU架构;32位系统上的最大值为4294967295(23 ...

  3. Kotlin基础篇(一)

    写在前面: 因为工作需要,目前转安卓开发,用的IDE是AS3.2版本,语言的话,用的是Kotlin.由于之前是做.NET的,没接触过这方面的东西,所以完全是小白一枚.所以想着开个博客,以此来记录自己的 ...

  4. JavaWeb基础—JSP

    一.什么是JSP JSP 全称是 Java Server Pages,是一种开发动态web资源的技术 在原HTML上添加JAVA脚本(灵魂工程师,为页面添加灵魂),可以说 jsp = html + j ...

  5. C# 用QQ企业邮箱发邮件

    问题System.Net.Mail下的SmtpClient来发送邮件,而System.Net.Mail only仅支持Explicit SSL 不要465端口,用25,不用EnableSsl = tr ...

  6. # 课堂测试(CH6)20155218

    课堂测试(CH6) 1. 下面代码中,对数组x填充后,采用直接映射高速缓存,所有对x和y引用的命中率为(D) A . 1 B . 1/4 C . 1/2 D . 3/4 解析:在x[0],y[0]时发 ...

  7. 二维码Data Matrix编码、解码使用举例

    二维码Data Matrix的介绍见: http://blog.csdn.net/fengbingchun/article/details/44279967  ,这里简单写了个生成二维码和对二维码进行 ...

  8. 解决Linux下编译.sh文件报错 unexpected operator Syntax error: word unexpected

    执行一个脚本  发现报语法错误,但是在其他机器上运行都没有问题 唯一的区别就是 一个是centos机器  报错的是ubuntu 网上搜索了一下 因为Ubuntu默认的sh是连接到dash的,又因为da ...

  9. python基础—字典

    阅读文本需要3分钟,不建议跳读 节目清单 字典是python中最重要的数据类型,字典由“键-值”对组成的集合,字典中的“值”通过“键”来引用.这里将介绍字典的定义.访问.排序等功能. 字典的创建 字典 ...

  10. Flutter - 创建横跨所有页面的侧滑菜单

    前一篇博客讲到了如何创建侧滑菜单,但是再实际使用过程中,会发现,这个策划菜单只能在首页侧滑出来. 当导航到其他页面后,侧滑就不管用了.这也有点不符合良好的用户体验设计.Google Play就是很好的 ...