前段时间在做一个微信的项目,遇到了一个上传图片的问题,花了一下午,解决了这个问题,然后把总结出来的代码,分享了出来。

最近又有一个图片+语音的功能, 更是蛋疼, 本次采用的不是File文件上传,然后转码(Base64)的形式解决的,而是使用微信的开放Js-SDK实现的。

我们.net苦逼的很,微信官方的Demo上,有php、java、nodejs以及python的示例代码,就是没有我们.NET的,不知道大神们是不是都藏私了,现在大的不出来,做小的出来顶!d=====( ̄▽ ̄*)b 

(开句玩笑话,别当真,鄙人菜鸟一枚)

闲话不聊, 马上进入正题

首先,我们看看官方给的 Js-SDK  https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421141115&token=&lang=zh_CN

…… 文档相信大家已经不陌生了,如何配置才是问题, 接下来,给大家详解 微信Js-SDK的调用(顺带给大家介绍下使用,老手可以直接跳过前戏~ 一、二、三、四)

 第一步: 绑定域名 

域名是指安全回调的域名 , 首先打开属于你的公众号,

点开 公众号设置 -  功能设置  - 设置安全回调域名

如图: 

设置好安全回调的域名以后, 下面进入第二步

第二步: 引入JS-SDK文件 

官方已经给出了地址, 我们直接在对应的页面中 引用这个JS即可, 这个JS里面的东西, 有微信已经封装好的交互(深究的话,鄙人暂时无能为力),直接引入即可

<script src="http://res.wx.qq.com/open/js/jweixin-1.0.0.js"></script>  类似这样的 

第三步: 通过config接口注入权限验证配置

从这个时候开始, 我们就需要配置调用 JS-SDK里面的方法了;

所有需要使用JS-SDK的页面必须先注入配置信息,否则将无法调用(同一个url仅需调用一次,对于变化url的SPA的web app可在每次url变化时进行调用,目前Android微信客户端不支持pushState的H5新特性,所以使用pushState来实现web app的页面会导致签名失败,此问题会在Android6.2中修复)。

wx.config({

debug: true, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。

appId: '', // 必填,公众号的唯一标识

timestamp: , // 必填,生成签名的时间戳

nonceStr: '', // 必填,生成签名的随机串

signature: '',// 必填,签名,见附录1

jsApiList: [] // 必填,需要使用的JS接口列表, 可参考官方的目录,添加以后,可以使用该接口

});

下面是我在MVC里配置的代码附录

控制器端:

var appId = WeixinConfig.AppID;
var nonceStr = Util.CreateNonce_str();
var timestamp = Util.CreateTimestamp();
var domain = System.Configuration.ConfigurationManager.AppSettings["Domain"];
var url = domain + Request.Url.PathAndQuery;
var jsTickect = WeixinConfig.TokenHelper.GetJSTickect();
var string1 = "";
var signature = JSAPI.GetSignature(jsTickect, nonceStr, timestamp, url, out string1);
ViewBag.JSAPI = new JSSDKModel
{
appId = appId,
nonceStr = nonceStr,
signature = signature,
timestamp = timestamp,
string1 = string1,
};
@VIew页面端:

 //配置微信
wx.config({
debug: false,
appId: '@ViewBag.JSAPI.appId', // 必填,公众号的唯一标识
timestamp: @ViewBag.JSAPI.timestamp, // 必填,生成签名的时间戳
nonceStr: '@ViewBag.JSAPI.nonceStr', // 必填,生成签名的随机串
signature: '@ViewBag.JSAPI.signature',// 必填,签名,见附录1
jsApiList: [
'chooseImage',
'previewImage',
'uploadImage',
'downloadImage',
'checkJsApi',
'startRecord',
'stopRecord',
'onVoiceRecordEnd',
'playVoice',
'pauseVoice',
'stopVoice',
'onVoicePlayEnd',
'uploadVoice',
'downloadVoice',
'getNetworkType'
]
});

配置完成后,我们进入第四步。

第四步: 接口验证

官方给的验证方法有 Ready 成功验证 和 Error 失败验证,下面我们看看代码

wx.ready(function(){
// config信息验证后会执行ready方法,所有接口调用都必须在config接口获得结果之后,config是一个客户端的异步操作,所以如果需要在页面加载时就调用相关接口,则须把相关接口放在ready函数中调用来确保正确执行。对于用户触发时才调用的接口,则可以直接调用,不需要放在ready函数中。
}); wx.error(function(res){
// config信息验证失败会执行error函数,如签名过期导致验证失败,具体错误信息可以打开config的debug模式查看,也可以在返回的res参数中查看,对于SPA可以在这里更新签名。
});

  

再看看官方的接口调用说明:

所有接口通过wx对象(也可使用jWeixin对象)来调用,参数是一个对象,除了每个接口本身需要传的参数之外,还有以下通用参数:

1.success:接口调用成功时执行的回调函数。

2.fail:接口调用失败时执行的回调函数。

3.complete:接口调用完成时执行的回调函数,无论成功或失败都会执行。

4.cancel:用户点击取消时的回调函数,仅部分有用户取消操作的api才会用到。

5.trigger: 监听Menu中的按钮点击时触发的方法,该方法仅支持Menu中的相关接口。

备注:不要尝试在trigger中使用ajax异步请求修改本次分享的内容,因为客户端分享操作是一个同步操作,这时候使用ajax的回包会还没有返回。

以上几个函数都带有一个参数,类型为对象,其中除了每个接口本身返回的数据之外,还有一个通用属性errMsg,其值格式如下:

调用成功时:"xxx:ok" ,其中xxx为调用的接口名

用户取消时:"xxx:cancel",其中xxx为调用的接口名

调用失败时:其值为具体错误信息

了解了以上信息以后,接下来就可以进入我们今天主要探讨的一个问题了——微信的图片接口和语音接口

我们先看图片接口,然后一一实验

图像接口
拍照或从手机相册中选图接口
wx.chooseImage({
count: 1, // 默认9
sizeType: ['original', 'compressed'], // 可以指定是原图还是压缩图,默认二者都有
sourceType: ['album', 'camera'], // 可以指定来源是相册还是相机,默认二者都有
success: function (res) {
var localIds = res.localIds; // 返回选定照片的本地ID列表,localId可以作为img标签的src属性显示图片
}
});
预览图片接口
wx.previewImage({
current: '', // 当前显示图片的http链接
urls: [] // 需要预览的图片http链接列表
});
上传图片接口
wx.uploadImage({
localId: '', // 需要上传的图片的本地ID,由chooseImage接口获得
isShowProgressTips: 1, // 默认为1,显示进度提示
success: function (res) {
var serverId = res.serverId; // 返回图片的服务器端ID
}
});
备注:上传图片有效期3天,可用微信多媒体接口下载图片到自己的服务器,此处获得的 serverId 即 media_id。
下载图片接口
wx.downloadImage({
serverId: '', // 需要下载的图片的服务器端ID,由uploadImage接口获得
isShowProgressTips: 1, // 默认为1,显示进度提示
success: function (res) {
var localId = res.localId; // 返回图片下载后的本地ID
}
});

关于图片这边,微信官方提供了四大接口,分别是选择图片的接口, 这个选择类似于微信的图片选择,其实就是JS和微信的交互体验,

选择一个一个接口解释

选择图片接口
chooseImage

 :在选择好图片以后,图片有一个localId返回,这个localId是微信缓存本地的一个ID,可以直接使用这个localId,进行图片显示,

例如:  $("#img").append('<img src="'+localId+'" style="width:50px; height:50px;"/> <br />'); 这样的一句话,会在img标签里面,添加一张刚刚你选择的图片

预览图片接口
previewImage

:我们注意到,这个预览图片的接口,有两个参数, 一个是 current ,一个 urls  , 这两个参数是什么意思呢? 首先, 不管是current 还是 urls , 里面的属性值, 都是http:// 的 需要预览的图片的地址, current 表示在调用这个接口时

会显示在第一页的图片, 而urls是表示,显示的图片集合 , 例如 :

var imgList = [
'http://h.hiphotos.baidu.com/image/pic/item/4bed2e738bd4b31c70a6b76782d6277f9f2ff850.jpg',
];
wx.previewImage({
current: imgList[0],
urls: imgList
});

  

这样,当点击的事件触发到这个方法后,会调用这个预览接口,实现微信端看到的,点小图, 看到大图的效果

上传图片接口
uploadImage 上传图片这个接口,很多人有这样的疑问(包括我第一次也是): 这个上传的图片在哪? 上传到哪儿了去了? 我们怎么才能用这个图片? 接下来,我感同身受的,一个一个解决这个问题。 疑: 上传的图片在哪里? - 答 : 我们注意到,之前在调用选择图片的接口的时候,有一个localId , 我解释过,是微信端缓存本地的一个图片编号,那么,我们联想一下, 这个localId ,是否就是选择得到的localId了, 没有错, 就是这个localId, 那也就是说, 我们想要使用上传接口, 首先, 我们得选择图片,才能进行相应的上传操作。 疑: 上传到哪儿去了? - 答: 当存在这个localId的时候,接口会找到相对应的图片上,然后把该图片,通过另一个接口 : https://api.weixin.qq.com/cgi-bin/media/upload?access_token=ACCESS_TOKEN&type=TYPE 上传至微信服务器的临时素材里面,当然,这个临时素材只有三天,并且有空间限制, 具体参考微信公众号里面的接口权限一栏 。 疑: 我们怎么才能用这个图片? - 答: 当调用图片上传接口成功, 会有一个返回值返回给我们 ,类型是这样的- {"type":"TYPE","media_id":"MEDIA_ID","created_at":123456789} , 我们需要注意到的有用的信息 就是这个 media_id ,这个media_id 表示我们所上传的素材, 在素材库里的位置, 当我们想要使用它的时候, 只需要把这个 media_id 还有 token 请求到素材请求的地址, 就可以得到使用这个素材了。
下载图片接口
downloadImage 其实在上一个接口里面,稍稍已经提到过这个接口的使用, 没有错, 这个接口就是为了下载临时的素材,然后返回一个localId, 此时的localId, 是一个全新的, 代表的是下载到的图片的localId, 使用的方法也还是很简单, 通过一个 Src 属性即可使用 讲到这里, 不得不停一下, 我们似乎忽略了些什么东西了,这些图片只能用三天,那三天后怎么办? 还有啊, 这个素材库有大小的限制, 不够了怎么办?
怎么办? 问我好咯, 我来分享一个办法—— 那就是转存到我们的服务器上, 微信已经替我们压缩了,我们下载下来, 然后转一下,送到我们自己的服务器上,留个地址,在我们的数据库存储一下,
一张可以持久高清无码图, 就这样被我们收入“囊中”。 下面继续贴代码, 看不懂的私聊,
  <a href="javascript:void(0);" onclick="javascript:chooseImage();">选择图片</a>
<a href="javascript:void(0);" onclick="javascript:uploadImage();">图片上传</a>
<a href="javascript:void(0);" onclick="javascript:downloadImage();">图片下载</a>
<a href="javascript:void(0);" onclick="javascript:previewImage();">图片预览</a>
<div id="img">选择的图片</div>
<div id="img2"> 下载的图片</div> <script type="text/javascript">
wx.config({
debug: false,
appId: '@ViewBag.JSAPI.appId', // 必填,公众号的唯一标识
timestamp: @ViewBag.JSAPI.timestamp, // 必填,生成签名的时间戳
nonceStr: '@ViewBag.JSAPI.nonceStr', // 必填,生成签名的随机串
signature: '@ViewBag.JSAPI.signature',// 必填,签名,见附录1
jsApiList: [
'chooseImage',
'previewImage',
'uploadImage',
'downloadImage',
'checkJsApi',
'startRecord',
'stopRecord',
'onVoiceRecordEnd',
'playVoice',
'pauseVoice',
'stopVoice',
'onVoicePlayEnd',
'uploadVoice',
'downloadVoice',
'getNetworkType'
]
}); wx.ready(function () {
//返回网络类型
wx.getNetworkType({
success: function (res) {
var networkType = res.networkType; // 返回网络类型2g,3g,4g,wifi
jQuery(function() {
$('#networkType').html(networkType);
});
}
});
}); // 5.1 拍照、本地选图
var images = {
localId: [],
serverId: []
}; function chooseImage() {
wx.chooseImage({
success: function (res) {
images.localId = res.localIds;
jQuery(function(){
$.each(res.localIds, function(i, n){
$("#img").append('<img src="'+n+'" style="width:50px; height:50px;"/> <br />');
});
});
}
});
} // 5.2 图片预览
function previewImage()
{
var imgList = [
'http://h.hiphotos.baidu.com/image/pic/item/4bed2e738bd4b31c70a6b76782d6277f9f2ff850.jpg',
];
wx.previewImage({
current: imgList[0],
urls: imgList
});
} // 5.3 上传图片
var i = 0, length =0;
function uploadImage(){
if (images.localId.length == 0) {
alert('请先使用选择图片按钮');
return;
}
length= images.localId.length;
upload();
} function upload() {
wx.uploadImage({
localId: images.localId[i],
success: function (res) {
i++;
//alert('已上传:' + i + '/' + length);
images.serverId.push(res.serverId);
$("#img2").append('<img src="'+res.localId+'" style="width:50px; height:50px;"/ /> <br />');
downloadImage(res.serverId);
if (i < length) {
upload();
}
},
fail: function (res) {
alert(JSON.stringify(res));
}
});
} //下载图片
function downloadImage(serverId)
{
$.get("@Url.Action("WeixinDownloadImage","Home")",{mediaId:serverId},function(data){
alert(data);
},"json")
} wx.error(function (res) {
alert(res.errMsg);
}); </script>

  

 

注意到,我有定义一个全局变量, 可以拓展到多图上传, 还有一个递归的上传。 我先回去了,下班了,回家烧饭吃。

服务器端的,和语音的,下次再聊。

【原创】.Net 微信 JS-SDK图片、语音上传接口的实现(MVC)-(一 、上传图片)的更多相关文章

  1. js实现图片粘贴上传到服务器并展示

    最近看了一些有关于js实现图片粘贴上传的demo,实现如下: (这里只能检测到截图粘贴和图片右键复制之后粘贴) demo1: document.addEventListener('paste', fu ...

  2. springmvc图片文件上传接口

    springmvc图片文件上传 用MultipartFile文件方式传输 Controller package com.controller; import java.awt.image.Buffer ...

  3. js压缩图片并上传,不失真,保证图片清晰度

    <!DOCTYPE HTML> <html lang="zh-CN"> <head> <meta charset="UTF-8& ...

  4. [组件封装]微信小程序-图片批量上传照片墙

    描述 批量上传图片, 可设置最大上传个数, 可删除, 可设置默认值. 效果 源码 pictures-wall.wxml <view class="picturesWall"& ...

  5. 基于vue + axios + lrz.js 微信端图片压缩上传

    业务场景 微信端项目是基于Vux + Axios构建的,关于图片上传的业务场景有以下几点需求: 1.单张图片上传(如个人头像,实名认证等业务) 2.多张图片上传(如某类工单记录) 3.上传图片时期望能 ...

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

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

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

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

  8. 微信js-sdk,选择图片,上传,下载到本地,php服务端

    //前端js代码<script> //客户端6.0.2 wx.config({ //debug:true, appId: "{pigcms:$signPackage.appId} ...

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

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

随机推荐

  1. ie9以下提示用户升级浏览器

    <!--[if lt IE 9]> <div style='border: 4px solid #FFF500; background: #FDFDC8; text-align: c ...

  2. Django - 获取表单数据的三种方式

    1.query set 对象 2.字典 3.query set 元组 备注:对象通过 ”对象.列名"方式访问,元组通过“对象.索引”方式访问.

  3. Yin and Yang Stones(思路题)

    Problem Description: A mysterious circular arrangement of black stones and white stones has appeared ...

  4. Scrapy实战:爬取http://quotes.toscrape.com网站数据

    需要学习的地方: 1.Scrapy框架流程梳理,各文件的用途等 2.在Scrapy框架中使用MongoDB数据库存储数据 3.提取下一页链接,回调自身函数再次获取数据 重点:从当前页获取下一页的链接, ...

  5. Linux之加密(基于key认证、建立私有云CA)

    对称加密: 一般的加密是用一个密码加密文件,解密用同样的密码,加密解密用一把密钥 非对称加密: 一个密码加密文件,解密却用另外一组密码,意思就是加密解密的密码不一样,其结果就是用这一组密钥中的一个来加 ...

  6. BZOJ 2038 2009国家集训队 小Z的袜子【模板·莫队】

    [题解] 1,先说说莫队算法. 莫队算法是用来离线处理区间问题的算法.非常易于理解和使用,且运用十分广泛. 假设我们现在已知区间[L,R]的答案,如果我们能以较低的时间复杂度扩展得到区间$[L-1,R ...

  7. Html学习总结(2)——Html页面head标签元素的意义和应用场景

    相信在html5之前,很少人会关注html页面上head里标签元素的定义和应用场景,可能记得住的只有"title"."keyword"和"descri ...

  8. codevs——T1214 线段覆盖

    http://codevs.cn/problem/1214/  时间限制: 1 s  空间限制: 128000 KB  题目等级 : 黄金 Gold 题解  查看运行结果     题目描述 Descr ...

  9. PHP中echo和print的区别

    这篇文章主要介绍了PHP中echo和print的区别,针对二者使用中常见的用法区别进行了较为深入的总结与分析,需要的朋友可以参考下 一般来说,PHP中动态输出HTML内容,是通过print 和 ech ...

  10. MFS搭建

    MooseFS是一个分布式存储的框架,其具有如下特性:     1.Free(GPL)     2.通用文件系统,不需要修改上层应用就可以使用     3.可以在线扩容,体系架构可伸缩性极强.     ...