微信JS-SDK实现上传图片功能
最近在项目开发中,有一个在微信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实现上传图片功能的更多相关文章
- 实战微信JS SDK开发:贺卡制作与播放(1)
前段时间忙于CanTK 2.0的开发,所以博客一直没有更新.CanTK 2.0主要增强了游戏和富媒体的开发,现在编码和测试基本完成了,等文档完成了再正式发布,里面有不少激动人心的功能,等发布时再一一细 ...
- 微信JS SDK接入的几点注意事项
微信JS SDK接入,主要可以先参考官网说明文档,总结起来有几个步骤: 1.绑定域名:先登录微信公众平台进入“公众号设置”的“功能设置”里填写“JS接口安全域名”.备注:登录后可在“开发者中心”查看对 ...
- 微信js sdk上传多张图片
微信js sdk上传多张图片,微信上传多张图片 该案例已tp3.2商城为例 直接上代码: php代码: public function ind(){ $appid="111111111111 ...
- 微信js SDK接口
微信JS-SDK说明文档 http://mp.weixin.qq.com/wiki/7/aaa137b55fb2e0456bf8dd9148dd613f.html 一.微信登录功能 在进行微信OAut ...
- 微信JS SDK配置授权,实现分享接口
微信开放的JS-SDK面向网页开发者提供了基于微信内的网页开发工具包,最直接的好处就是我们可以使用微信分享.扫一扫.卡券.支付等微信特有的能力.7月份的时候,因为这个分享的证书获取问题深深的栽了一坑, ...
- 微信开发(2):微信js sdk分享朋友圈,朋友,获取config接口注入权限验证(转)
进行微信开发已经一阵子了,从最初的什么也不懂,到微信授权登录,分享,更改底部菜单,素材管理,等. 今天记录一下微信jssdk 的分享给朋友的功能,获取config接口注入. 官方文档走一下简单说:四步 ...
- 调用微信js sdk
场景:需要调用微信获取当前位置的借口. 途径:查看微信 https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421141115 .后 ...
- 微信JS SDK使用权限签名算法
jsapi_ticket 生成签名之前必须先了解一下jsapi_ticket,jsapi_ticket是公众号用于调用微信JS接口的临时票据.正常情况下,jsapi_ticket的有效期为7200秒, ...
- 微信js sdk分享开发摘记java版
绑定域名和引入js的就不说了 废话不说直接上代码 public void share(HttpServletRequest request) throws Exception { StringBuff ...
- 微信JS SDK Demo 官方案例[转]
摘要: 微信JS-SDK是微信公众平台面向网页开发者提供的基于微信内的网页开发工具包. 通过使用微信JS-SDK,网页开发者可借助微信高效地使用拍照.选图.语音.位置等手机系统的能力,同时可以直接使用 ...
随机推荐
- 【转】Android随笔之——PackageManager详解
参考:http://www.cnblogs.com/xingfuzzhd/p/3374504.html 今天要讲的是PackageManager.Android系统为我们提供了很多服务管理的类,包括A ...
- 1、JVM-走进java
1.1.概述 Java不仅仅是一门编程语言,还是一个由一系列计算机软件和规范形成的技术体系,这个技术体系提供了完整的用于软件开发和跨平台部署的支持环境,并广泛应用于嵌入式系统.移动终端.企业服务器.大 ...
- [图解tensorflow源码] Session::Run()流程图 (单机版)
- ORM增删改查(django)
单表操作: 一.添加 (1)方式一 from mysite.models import * def add(request): book= Book(name="python" ...
- MySql优化分析
原理 MYSQL逻辑分层 :连接层 服务层 引擎层 存储层 InnoDB(默认) :事务优先 (适合高并发操作:行锁) MyISAM :性能优先 (表锁) SQL优化 编写过程: sql select ...
- uboot-2012.04.01移植编译前准备
一:准备移植1.从下面的官网下载uboot-2012.04.012.建立sourceinsight工程 a.解压并在E:\colin weidongshan\transplant_u-boot-201 ...
- 后台生成excel前端下载
后台生成Excel时前端获取下载 Controller控制器: package com.example.test.controller; import com.example.test.common. ...
- RMAN 与control文件和spfile文件的备份
以10.2为例,官方文档如此说: http://docs.oracle.com/cd/B19306_01/backup.102/b14191/rcmconc1.htm The RMAN behavio ...
- lxml etree xpath
from lxml import etree #####################基本用法: ##################### html = ''' <h1 class=&quo ...
- setInterval只执行一次的原因
setInterval(arrow(),) 改为: setInterval(arrow,) 原因: arrow()这是一个函数调用,函数调用就会有返回值, 而arrow()没有返回值,所以这里的arr ...