最近在项目开发中,有一个在微信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. Python学习之路 (三)爬虫(二)

    通用爬虫和聚焦爬虫 根据使用场景,网络爬虫可分为 通用爬虫 和 聚焦爬虫 两种. 通用爬虫 通用网络爬虫 是 捜索引擎抓取系统(Baidu.Google.Yahoo等)的重要组成部分.主要目的是将互联 ...

  2. 【Agile123】Automated Test in Agile

    https://www.infoq.com/articles/thoughts-on-test-automation-in-agile Start Small Balance the cost vs. ...

  3. nodejs的expresss中post的req.body总是undefined的原因

    1)因为express将body-parser分离了出来,所以你需要手动添加进下面的内容即可 var path = require('path'); var bodyParser = require( ...

  4. 《You dont know JS》原生函数

    原生函数 原生函数,即JavaScript的内建函数(built-in function).常用的原生函数有String().Number().Boolean().Array().Object().F ...

  5. 如何接好CAN的“地”

    [导读]CAN总线以其高可靠性.实时性.灵活性以及严谨的数据处理机制等特点,在工业现场和汽车行业得到广泛应用,但随着环境干扰以及节点数目的增加等对CAN总线的稳定性提出更高的要求,而面对电源地.信号地 ...

  6. 【js】插件—动效Velocity.js

    Velocity.js——加速JavaScript动画 一款替代jQuery的$ .animate()动效的插件.兼容IE8和Android2.3及以上. 相比较优点: 1.它比JQuery更快,并实 ...

  7. 对ArrayList存放的对象,按照对象的某个属性进行排序。

    使用Collections.sort()方法进行实现: import java.util.ArrayList; import java.util.Collections; import java.ut ...

  8. 学习JavaSE TCP/IP协议与搭建简易聊天室

    一.TCP/IP协议 1.TCP/IP协议包括TCP.IP和UDP等 2.域名通过dns服务器转换为IP地址 3.局域网可以通过IP或者主机地址寻找到相应的主机 4.TCP是可靠的连接,效率低,且连接 ...

  9. 展开label,利用YYText实现文字显示不完末尾添加全文

    效果图: 操作 先github下载<YYText>文件导入, 代码如下: #import "ViewController.h" #import "YYLabe ...

  10. 0CO_PC_01 成本对象控制: 计划/实际数据

    用户提出要取生产订单的成本分析明细,分析目标和实际的差异. 查了一下,可以使用 BW标准数据源:0CO_PC_01 其中,值类型:10(实际).20(计划).30(目标) 货币类型:20(成本控制范围 ...