这篇文章主要为大家详细介绍了php微信公众账号开发之五个坑,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
菜单回复是需要处理xml文件的,我们根据微信返回的xml文件,可以得到每个微信用户相对于微信公众号的唯一标识。微信公众平台的机制简单的将就是我们自己输出固定格式的xml文件,然后微信app负责解析,得到我们想要的信息,然后对信息统一处理。
第六坑,如果你看微信文档,那么,绝对坑死你,上图。这里的tousername和fromusername一定特么的要分清楚了,记住,千万不要写反了,用户对于微信而言是a→b,那么微信对于用户就是反着来的,貌似现在应该说清楚了。
/// <summary>
/// 接收微信发送的xml消息并且解析
/// </summary>
private void receivexml()
{
try
{
stream requeststream = system.web.httpcontext.current.request.inputstream;
byte[] requestbyte = new byte[requeststream.length];
requeststream.read(requestbyte, 0, (int)requeststream.length);
string requeststr = encoding.utf8.getstring(requestbyte);
if (!string.isnullorempty(requeststr))
{
//封装请求类
xmldocument requestdocxml = new xmldocument();
requestdocxml.loadxml(requeststr);
xmlelement rootelement = requestdocxml.documentelement;
wxxmlmodel wxxmlmodel = new wxxmlmodel();
if (rootelement != null)
{
wxxmlmodel.tousername = rootelement.selectsinglenode("tousername") == null ? "" : rootelement.selectsinglenode("tousername").innertext;
wxxmlmodel.fromusername = rootelement.selectsinglenode("fromusername") == null ? "" : rootelement.selectsinglenode("fromusername").innertext;
wxxmlmodel.createtime = rootelement.selectsinglenode("createtime") == null ? "" : rootelement.selectsinglenode("createtime").innertext;
wxxmlmodel.msgtype = rootelement.selectsinglenode("msgtype") == null ? "" : rootelement.selectsinglenode("msgtype").innertext;
switch (wxxmlmodel.msgtype)
{
case "text"://文本
wxxmlmodel.content = rootelement.selectsinglenode("content") == null ? "" : rootelement.selectsinglenode("content").innertext;
break;
case "image"://图片
wxxmlmodel.picurl = rootelement.selectsinglenode("picurl") == null ? "" : rootelement.selectsinglenode("picurl").innertext;
break;
case "event"://事件
wxxmlmodel.event = rootelement.selectsinglenode("event") == null ? "" : rootelement.selectsinglenode("event").innertext;
if (wxxmlmodel.event != "templatesendjobfinish")//关注类型
{
wxxmlmodel.eventkey = rootelement.selectsinglenode("eventkey") == null ? "" : rootelement.selectsinglenode("eventkey").innertext;
}
break;
default:
break;
}
}
responsexml(wxxmlmodel);//回复消息
}
}
catch (exception ee)
{
//记录错误日志
}
}
/// <summary>
/// 回复消息
/// </summary>
/// <param name="wxxmlmodel"></param>
private void responsexml(wxxmlmodel wxxmlmodel)
{
string xml = "";
switch (wxxmlmodel.msgtype)
{
case "text"://文本回复
var info = oauth.getuserinfo(tools.wa_getaccess_token.isexistaccess_token(), wxxmlmodel.fromusername);
tools.waentity.oauthuser user = tools.jsonhelper.parsefromjson<tools.waentity.oauthuser>(info);
var content = wxxmlmodel.content.toupper();
string ncbacturl = configurationmanager.appsettings["ncbacturl"];
string appid = configurationmanager.appsettings["appid"];
if (content.contains("t"))//接受的文字如果包含t
{
//业务处理
}
else
{
xml = responsemessage.retext(wxxmlmodel.fromusername, wxxmlmodel.tousername, "/:rose农场大数据欢迎你!/:rose");
}
break;
case "event":
switch (wxxmlmodel.event.tolower())
{
case "subscribe":
if (string.isnullorempty(wxxmlmodel.eventkey))
{
xml = responsemessage.retext(wxxmlmodel.fromusername, wxxmlmodel.tousername, "关注成功!/:rose");
}
else
{
xml = responsemessage.subscanqrcode(wxxmlmodel.fromusername, wxxmlmodel.tousername, wxxmlmodel.eventkey);//扫描带参数二维码先关注后推送事件
}
break;
case "scan":
xml = responsemessage.scanqrcode(wxxmlmodel.fromusername, wxxmlmodel.tousername, wxxmlmodel.eventkey);//扫描带参数二维码已关注 直接推送事件
break;
case "click"://处理单击事件
if (wxxmlmodel.eventkey == "p1")
{
//自己的业务逻辑
}
else
{
//自己的业务逻辑
}
break;
case "unsubscribe"://取消关注
break;
}
break;
default://默认回复
break;
}
response.write(xml);//输出组织的xml信息
}
这就是菜单的信息处理,不明真相的群众貌似会问那个所谓的responsemessage到底有几个意思呢,ok,我已经无力吐槽我这三天研究出来的微信公共平台的东西了。
public class responsemessage
{
#region 接收的类型
/// <summary>
/// 接收文本
/// </summary>
/// <param name="fromusername"></param>
/// <param name="tousername"></param>
/// <param name="content"></param>
/// <returns></returns>
public static string gettexttest(string fromusername, string tousername, string content, string key)
{
commonmethod.writetxt(content);//接收的文本消息
string xml = "";
switch (content)
{
case "关键字":
xml = retext(fromusername, tousername, "关键词回复测试——兴农丰华:" + key);
break;
case "单图文":
xml = rearticle(fromusername, tousername, "测试标题", "测试详情——兴农丰华:" + key, "http://www.xnfhtech.com/templets/boze/images/20120130083143544.gif", "http://www.xnfhtech.com/");
break;
default:
xml = retext(fromusername, tousername, "无对应关键字——兴农丰华:" + key);
break;
}
return xml;
}
/// <summary>
/// 未关注扫描带参数二维码
/// </summary>
/// <param name="fromusername"></param>
/// <param name="tousername"></param>
/// <param name="eventkey"></param>
/// <returns></returns>
public static string subscanqrcode(string fromusername, string tousername, string eventkey)
{
return "";
}
/// <summary>
/// 已关注扫描带参数二维码
/// </summary>
/// <param name="fromusername"></param>
/// <param name="tousername"></param>
/// <param name="eventkey"></param>
/// <returns></returns>
public static string scanqrcode(string fromusername, string tousername, string eventkey)
{
return "";
}
#endregion
#region 回复方式
/// <summary>
/// 回复文本
/// </summary>
/// <param name="fromusername">发送给谁(openid)</param>
/// <param name="tousername">来自谁(公众账号id)</param>
/// <param name="content">回复类型文本</param>
/// <returns>拼凑的xml</returns>
public static string retext(string fromusername, string tousername, string content)
{
string xml = "<xml><tousername><![cdata[" + fromusername + "]]></tousername><fromusername><![cdata[" + tousername + "]]></fromusername>";//发送给谁(openid),来自谁(公众账号id)
xml += "<createtime>" + commonmethod.convertdatetimeint(datetime.now) + "</createtime>";//回复时间戳
xml += "<msgtype><![cdata[text]]></msgtype>";//回复类型文本
xml += "<content><![cdata[" + content + "]]></content><funcflag>0</funcflag></xml>";//回复内容 funcflag设置为1的时候,自动星标刚才接收到的消息,适合活动统计使用
return xml;
}
/// <summary>
/// 回复单图文
/// </summary>
/// <param name="fromusername">发送给谁(openid)</param>
/// <param name="tousername">来自谁(公众账号id)</param>
/// <param name="title">标题</param>
/// <param name="description">详情</param>
/// <param name="picurl">图片地址</param>
/// <param name="url">地址</param>
/// <returns>拼凑的xml</returns>
public static string rearticle(string fromusername, string tousername, string title, string description, string picurl, string url)
{
string xml = "<xml><tousername><![cdata[" + fromusername + "]]></tousername><fromusername><![cdata[" + tousername + "]]></fromusername>";//发送给谁(openid),来自谁(公众账号id)
xml += "<createtime>" + commonmethod.convertdatetimeint(datetime.now) + "</createtime>";//回复时间戳
xml += "<msgtype><![cdata[news]]></msgtype><content><![cdata[]]></content><articlecount>1</articlecount><articles>";
xml += "<item><title><![cdata[" + title + "]]></title><description><![cdata[" + description + "]]></description><picurl><![cdata[" + picurl + "]]></picurl><url><![cdata[" + url + "]]></url></item>";
xml += "</articles><funcflag>0</funcflag></xml>";
return xml;
}
/// <summary>
/// 多图文回复
/// </summary>
/// <param name="fromusername">发送给谁(openid)</param>
/// <param name="tousername">来自谁(公众账号id)</param>
/// <param name="articlecount">图文数量</param>
/// <param name="dtarticle"></param>
/// <returns></returns>
public static string rearticle(string fromusername, string tousername, int articlecount, system.data.datatable dtarticle)
{
string xml = "<xml><tousername><![cdata[" + fromusername + "]]></tousername><fromusername><![cdata[" + tousername + "]]></fromusername>";//发送给谁(openid),来自谁(公众账号id)
xml += "<createtime>" + commonmethod.convertdatetimeint(datetime.now) + "</createtime>";//回复时间戳
xml += "<msgtype><![cdata[news]]></msgtype><content><![cdata[]]></content><articlecount>" + articlecount + "</articlecount><articles>";
foreach (system.data.datarow item in dtarticle.rows)
{
xml += "<item><title><![cdata[" + item["title"] + "]]></title><description><![cdata[" + item["description"] + "]]></description><picurl><![cdata[" + item["picurl"] + "]]></picurl><url><![cdata[" + item["url"] + "]]></url></item>";
}
xml += "</articles><funcflag>0</funcflag></xml>";
return xml;
}
#endregion
}
ok,加上自己的逻辑代码,是不是完美的实现了回复?
第七坑,我真心不想计数了,你确定这个回复可以么?说真的,宝宝不确定,因为你写了之后知道在哪里调用么,我的乖乖,尼玛,服务器验证通过就把回复加上去是最保险的。我已经没有节操了。
接下来我们说什么呢,我们就说说获取用户信息这个东西吧,因为我们这些东西一般都是基于h5页面的。所以,就要用到之前我们配置的
这个东东,其实这个相对于前面的至少坑少了很多,真心的,宝宝就暂时不说他坑了。上个代码吧。
//微信网页授权2.0
public class oauth2
{
javascriptserializer jss = new javascriptserializer();
public oauth2() { }
/// <summary>
/// 对页面是否要用授权
/// </summary>
/// <param name="appid">微信应用id</param>
/// <param name="redirect_uri">回调页面</param>
/// <param name="scope">应用授权作用域snsapi_userinfo(不弹出授权页面,直接跳转,只能获取用户openid),snsapi_userinfo (弹出授权页面,可通过openid拿到昵称、性别、所在地。并且,即使在未关注的情况下,只要用户授权,也能获取其信息)</param>
/// <returns>授权地址</returns>
public string getcodeurl(string appid, string redirect_uri, string scope)
{
return string.format("https://open.weixin.qq.com/connect/oauth2/authorize?appid={0}&redirect_uri={1}&response_type=code&scope={2}&state=state#wechat_redirect", appid, redirect_uri, scope);
}
/// <summary>
/// 对页面是否要用授权
/// </summary>
/// <param name="appid">微信应用id</param>
/// <param name="redirect_uri">回调页面</param>
/// <param name="scope">应用授权作用域snsapi_userinfo(不弹出授权页面,直接跳转,只能获取用户openid),snsapi_userinfo (弹出授权页面,可通过openid拿到昵称、性别、所在地。并且,即使在未关注的情况下,只要用户授权,也能获取其信息)</param>
/// <returns>授权地址</returns>
public string getcodeurl(string appid, string redirect_uri, string scope,string state)
{
return string.format("https://open.weixin.qq.com/connect/oauth2/authorize?appid={0}&redirect_uri={1}&response_type=code&scope={2}&state={3}#wechat_redirect", appid, redirect_uri, scope, state);
}
/// <summary>
/// 用code换取openid 此方法一般是不获取用户昵称时候使用
/// </summary>
/// <param name="appid"></param>
/// <param name="appsecret"></param>
/// <param name="code">回调页面带的code参数</param>
/// <returns>微信用户唯一标识openid</returns>
public string codegetopenid(string appid, string appsecret, string code)
{
string url = string.format("https://api.weixin.qq.com/sns/oauth2/access_token?appid={0}&secret={1}&code={2}&grant_type=authorization_code", appid, appsecret, code);
string retext = commonmethod.webrequestpostorget(url, "");//post/get方法获取信息
dictionary<string, object> dictext = (dictionary<string, object>)jss.deserializeobject(retext);
if (!dictext.containskey("openid"))
return "";
return dictext["openid"].tostring();
}
/// <summary>
///用code换取获取用户信息(包括非关注用户的)
/// </summary>
/// <param name="appid"></param>
/// <param name="appsecret"></param>
/// <param name="code">回调页面带的code参数</param>
/// <returns>获取用户信息(json格式)</returns>
public string getuserinfo(string appid, string appsecret, string code)
{
string url = string.format("https://api.weixin.qq.com/sns/oauth2/access_token?appid={0}&secret={1}&code={2}&grant_type=authorization_code", appid, appsecret, code);
string retext = commonmethod.webrequestpostorget(url, "");//post/get方法获取信息
dictionary<string, object> dictext = (dictionary<string, object>)jss.deserializeobject(retext);
if (!dictext.containskey("openid"))
{
log.error("获取openid失败,错误码:" + dictext["errcode"].tostring());
return "";
}
else
{
return commonmethod.webrequestpostorget("https://api.weixin.qq.com/sns/userinfo?access_token=" + dictext["access_token"] + "&openid=" + dictext["openid"] + "&lang=zh_cn", "");
}
}
/// <summary>
/// 通过openid获取用户信息
/// </summary>
/// <param name="accesstoken"></param>
/// <param name="openid"></param>
/// <returns></returns>
public string getuserinfo(string accesstoken, string openid)
{
string url = string.format("https://api.weixin.qq.com/cgi-bin/user/info?access_token={0}&openid={1}&lang=zh_cn", accesstoken, openid);
return commonmethod.webrequestpostorget(url, "");//post/get方法获取信息
}
}
我们需要调用的时候直接用里面的方法,获取微信网页授权即可,比如对于a控制器下面的b视图要获取授权,并且要获取用户的相关信息,那么我们直接调用即可,如 getcodeurl(appid, "http://" + url + "/a/b", "snsapi_userinfo")
在这里我还是吐槽一下吧。
第八坑,微信菜单json的url拼接,里面的前面不是加了js验证么,so,特么的,还是乖乖的加上http://。
不过这里授权之后,因为用户的很多信息我们都要用到,这就是h5页面传值的问题,我在项目里面用的是session,直接写一个公用方法,如果session有值,则直接取值的。对于里面的一些东东,我想说明一下,并不是所有的代码都要贴出来,我这边的代码只是我个人认为需要贴出来的。所以里面的方法可能有大家看不到的,如果需要,可以留言本宝宝,谢谢。
public string getsession()
{
log.error("getsession");
string oauthstr = "";
try
{
if (session != null && (session["oauthstr"] == null || string.isnullorempty(session["oauthstr"].tostring())))
{
if (!string.isnullorempty(request.querystring["code"]))
{
oauth2 oauth = new oauth2();
string code = convert.tostring(request["code"]);
oauthstr = oauth.getuserinfo(configurationmanager.appsettings["appid"],
configurationmanager.appsettings["appsecret"], code);
session["oauthstr"] = oauthstr;
tools.waentity.oauthuser oauthuser = new tools.waentity.oauthuser();
oauthuser = tools.jsonhelper.parsefromjson<tools.waentity.oauthuser>(oauthstr);
}
return oauthstr;
}
else
{
tools.waentity.oauthuser oauthuser = new tools.waentity.oauthuser();
oauthuser = tools.jsonhelper.parsefromjson<tools.waentity.oauthuser>(session["oauthstr"].tostring());
return session["oauthstr"].tostring();
}
}
catch (exception e) { log.error(e.tostring()); return oauthstr; };
}
然后每次遇到需要获取信息的页面,我一般都是调用这个就可以了。
基本上剩下的都是我们自己要处理的业务逻辑了,继续说坑吧。
第九坑,微信上传图片,坑的绝对不只是自己。对于这个宝宝真的信了,不管你信不信。特么的图片不能for循环上传。当然,这个只限苹果机型,大android还是没有问题的。
前面说到了js安全验证的问题,这里就是调用这些个验证,请求一些应该的权限,然后获取图片信息等等。
放心好了,宝宝现在都是上图说话,没图说个小弟弟呀。。。。。
我们继续回来看代码。
先来个处理json的
public class jsapi
{
javascriptserializer jss = new javascriptserializer();
public jsapi() { }
const string url_format_ticket = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token={0}&type=jsapi";
#region 验证jsapi权限配置
/// <summary>
/// 获取jsapi权限配置的数组/四个参数
/// </summary>
/// <param name="appid">应用id</param>
/// <param name="appsecret">密钥</param>
/// <returns>json格式的四个参数</returns>
public string getjsapiinfo(string appid, string appsecret)
{
string jsapi_ticket = "";
//ticket 缓存7200秒
if (system.web.httpcontext.current.session["jsapi_ticket"] == null)
{
string ticketurl = string.format(url_format_ticket, basicapi.getaccesstoken(appid, appsecret));//"https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=" + getaccesstoken(appid, appsecret) + "&type=jsapi"
jsapi_ticket = commonmethod.webrequestpostorget(ticketurl, "");//basicapi.gettokensession
system.web.httpcontext.current.session["jsapi_ticket"] = jsapi_ticket;
system.web.httpcontext.current.session.timeout = 7200;
basicapi.writetxt("jsapi_ticket1:" + jsapi_ticket);
}
else
{
jsapi_ticket = system.web.httpcontext.current.session["jsapi_ticket"].tostring();
basicapi.writetxt("jsapi_ticket2:" + jsapi_ticket);
}
dictionary<string, object> respdic = (dictionary<string, object>)jss.deserializeobject(jsapi_ticket);
jsapi_ticket = respdic["ticket"].tostring();//获取ticket
string timestamp = commonmethod.convertdatetimeint(datetime.now).tostring();//生成签名的时间戳
string noncestr = commonmethod.getrandcode(16);//生成签名的随机串
string url = system.web.httpcontext.current.request.url.absoluteuri.tostring();//当前的地址
basicapi.writetxt("url:" + url);
string[] arraylist = { "jsapi_ticket=" + jsapi_ticket, "timestamp=" + timestamp, "noncestr=" + noncestr, "url=" + url };
array.sort(arraylist);
string signature = string.join("&", arraylist);
signature = formsauthentication.hashpasswordforstoringinconfigfile(signature, "sha1").tolower();
string r = "{\"appid\":\"" + appid + "\",\"timestamp\":" + timestamp + ",\"noncestr\":\"" + noncestr +
"\",\"signature\":\"" + signature +
"\",\"jsapilist\":[\"chooseimage\",\"previewimage\",\"uploadimage\",\"downloadimage\",\"scanqrcode\",\"onmenushareqq\"]}";
basicapi.writetxt("r:" + r.replace(" ", ""));
return r.replace(" ", "");
}
}
然后看具体调用。
后台代码其实很简单的,直接输出配置文件,然后前台js直接调用即可。
jsapi jsapi = new jsapi();
string config = jsapi.getjsapiinfo(appid, appsecret);
viewbag.config = config;
前台代码,其实也不难,这个有官方的例子的。
<script type="text/javascript">
wx.config(@html.raw(viewbag.config));//后台传递的微信配置文件
wx.ready(function () {
$("#avatar").click(function () {
wx.chooseimage({
count: 1, // 图片数量 默认9
sizetype: ['compressed'], // 可以指定是原图还是压缩图,默认二者都有'original',
sourcetype: ['album', 'camera'], // 可以指定来源是相册还是相机,默认二者都有
success: function (res) {
var localids = res.localids; // 返回选定照片的本地id列表,localid可以作为img标签的src属性显示图片
wx.uploadimage({
localid: '' + localids,
isshowprogresstips: 1,
success: function (res) {
serverid = res.serverid;
getwxphoto(serverid);
}
});
}
});
});
});
wx.error(function (res) {
alert("接口验证失败,详细信息:\n" + json.stringify(res));
});
var types = 1;
function getwxphoto(mediaid) {
$.ajax({
async: false,
type: "post",
url: "/activityregistration/downloadwxphoto",//自己的处理方法
data: { mediaid: mediaid, types: types },
success: function (data) {
$("#imageico").val(data.result);
$("#hed_pic").attr('src', ".." + data.result);
$("#hed_pic").attr('alt', "avatarimg");
}
});
}
</script>
ok,后台方法其实也很简单,就是一个二进制文件处理,不对,简单个蛋蛋,特么的,因为路径的问题,坑了宝宝一个小时,特么的。还有这里建议,等微信图片下载完成之后再给前台加载图片,保证每一个图片都加载完成,保证后台的图片的上传完成。
/// <summary>
/// 下载多媒体文件
/// </summary>
/// <param name="username">公众号</param>
/// <param name="mediaid">媒体id</param>
/// <param name="data">返回下载是否成功</param>
/// <param name="types">添加的图片类型</param>
/// <returns>返回多媒体文件数据;如果下载失败,返回null。</returns>
public jsonresult downloadwxphoto(string mediaid, int types)
{
errormessage errormessage;
string access_token = basicapi.getaccesstoken(configurationmanager.appsettings["appid"], configurationmanager.appsettings["appsecret"]);
byte[] data = mediahelper.download(access_token, mediaid, out errormessage);
string files = string.empty, filename = string.empty;
files = server.mappath("~/wxinphoto/");
if (!directory.exists(files))
{
directory.createdirectory(files);
}
filename = files + datetime.now.ticks + ".jpg";
if (data != null)
{
bool flag = writefile(data, filename);
if (flag)
{
errormessage = new errormessage(errormessage.successcode, "下载多媒体文件成功。");
}
else
{
errormessage = new errormessage(errormessage.exceptioncode, "从微信服务器下载多媒体文件失败。");
}
}
else
errormessage = new errormessage(errormessage.exceptioncode, "从微信服务器下载多媒体文件失败。");
return json(new { result = "/" + urlconvertor(filename), errormessage = errormessage });
}
//读filename到byte[]
private byte[] readfile(string filename)
{
filestream pfilestream = null;
byte[] preadbyte = new byte[0];
try
{
pfilestream = new filestream(filename, filemode.open, fileaccess.read);
binaryreader r = new binaryreader(pfilestream);
r.basestream.seek(0, seekorigin.begin); //将文件指针设置到文件开
preadbyte = r.readbytes((int)r.basestream.length);
return preadbyte;
}
catch
{
return preadbyte;
}
finally
{
if (pfilestream != null)
pfilestream.close();
}
}
//写byte[]到filename
private bool writefile(byte[] preadbyte, string filename)
{
filestream pfilestream = null;
try
{
pfilestream = new filestream(filename, filemode.openorcreate);
pfilestream.write(preadbyte, 0, preadbyte.length);
}
catch
{
return false;
}
finally
{
if (pfilestream != null)
pfilestream.close();
}
return true;
}
/// <summary>
/// 判断目标字节数组是否位于源字节数组的开始
/// </summary>
/// <param name="source">源字节数组</param>
/// <param name="target">目标字节数组</param>
/// <returns>返回目标字节数组是否位于源字节数组的开始</returns>
private bool startswithbytes(byte[] source, byte[] target)
{
if (source == null && target == null)
return true;
if (source == null && target != null || source != null && target == null)
return false;
if (source.length < target.length)
return false;
bool startswith = true;
for (int i = 0; i < target.length; i++)
{
if (source[i] != target[i])
{
startswith = false;
break;
}
}
return startswith;
}
是不是以为这就算完事了,我的乖乖,头像上传了,微信摄像头也特么该调用的调用了,宝宝好幸福,宝宝也是牛人一个了,记住前面的东东,宝宝还没有说坑呢。
来重复我们的第九个坑,特么的,你js写个for循环要是能循环把图片上传到后台,宝宝也服气,真的,宝宝服气。
直接说吧,最后我自己想了下,也和队友讨论了下,可能是因为微信有什么验证,导致之后一张图片上传成功之后,才能进行一张,但是我们iphone就是特么的特例,大android没用问题的,就是iphone有了问题,而且问题不小,上传四张图片吧,老特么是最后一张,最后,找到了万能的网友,感谢你,不过宝宝已经忘记了在哪里找到的了,尴尬了。。。。。。。。。。。
<script type="text/javascript">
var types = 2;
var urllist="";
var i = 0;
function up(resurl) {
if (i < resurl.localids.length) {
// 上传照片resu.localids[i]
wx.uploadimage({
localid: '' + resurl.localids[i],
isshowprogresstips: 1,
success: function (res) {
// alert("res.serverid:" + res.serverid);
mediaid = res.serverid;
$.ajax({
async: false,
type: "post",
url: "/activityregistration/downloadwxphoto",
data: { mediaid: mediaid, types: types },
success: function (data) {
$("#picpath").append('<li><p class="imgbox"><img src="/img/cechanadd.png" id="picture' + i + '" alt="" /></p></li>');
$("#picture" + i).attr('src', data.result);
$("#picpath").append('<input value=' + data.result + ' type="hidden" id="picurl' + i + '" class="picclass" />');
i++;
if (i == resurl.localids.length - 1) {
$("#picpath").append('<li><p class="imgbox"><img src="/img/cechanadd.png" id="picture" alt="" /></p></li>');
}
up(resurl);
}
});
}
});
} else {
i = 0;
}
}
//上传图片
wx.config(@html.raw(viewbag.config));
wx.ready(function () {
$("#picpath").click(function () {
wx.chooseimage({
count: 3, // 默认9
sizetype: ['compressed'], // 可以指定是原图还是压缩图,默认二者都有'original',
sourcetype: ['album', 'camera'], // 可以指定来源是相册还是相机,默认二者都有
success: function (resu) {
var localids = resu.localids; // 返回选定照片的本地id列表,localid可以作为img标签的src属性显示图片
if (localids.indexof("wxlocalresource") != -1) {
localids = localids.replace("wxlocalresource", "wxlocalresource");
}
@(index += 1)
if (localids != '') {
$("#picpath").html("");
var sear = new regexp(',');
if (sear.test(localids)) {
up(resu);
}
else {
$("#picpath").append(' <li><p class="imgbox"><img src="/img/cechanadd.png" id="picture' + '@index' + '" alt="" " /></p></li>');
$("#picture" + "@index").attr('src', localids);
// 上传照片
wx.uploadimage({
localid: '' + localids,
isshowprogresstips: 1,
success: function (res) {
mediaid = res.serverid;
$.ajax({
async: false,
type: "post",
url: "/activityregistration/downloadwxphoto",
data: { mediaid: mediaid, types: types },
success: function (data) {
$("#picpath").append('<input value=' + data.result + ' type="hidden" id="picurl' + @index + '" class="picclass" />');
$("#picpath").append('<li><p class="imgbox"><img src="/img/cechanadd.png" id="picture" alt="" /></p></li>');
}
});
}
});
}
// $("#picpath").append('<li><p class="imgbox"><img src="/img/cechanadd.png" id="picture" alt="" /></p></li>');
}
}
});
});
});
wx.error(function (res) {
alert("接口验证失败,详细信息:\n" + json.stringify(res));
});
</script>
请记住,递归就特么可以了。
说到这里,宝宝已经不想多说什么了,特么的产品你能不能不装逼,你特么见过那个微信能回复一个信息直接跳转网页的,你咋不去屎呢,联想到前几天大阿里的月饼时间,突然感觉我们程序员挺悲剧的,成功的都是特么的产品,然后出问题的都是我们程序员的锅?试问一下,这个锅真心我们程序员该背么。
算了,还是不吐槽了,已经无力了。。。。宝宝92年降临,现在确实82年的皮肤呀,唉,宝宝累了,真的。
顺便给点h5页面的建议吧。比如当点击返回键的时候,我们需要刷新页面的时候,就是所谓的判断页面要不要刷新,这里有很多种方法,但是微信里面宝宝还是觉得这么干靠谱。
<script type="text/javascript">
if (window.name != "hasload") {
location.reload();
window.name = "hasload";
} else {
window.name = "";
}
</script>
还有,那个微信执行完成之后想直接退出当前界面进入微信公众号界面的,直接调用微信的一个内置的方法即可。记得写到3f1c4e4b6b16bbbd69b2ee476dc4f83a2cacc6d41bbb37262a98f745aa00fbf0里面。
weixinjsbridge.call('closewindow'); //这是微信关闭当前网页
这么自信的以为自己搞定了所有,你跑呀,你要跑起来,嗯哼,别不服气。
微信公众账号指第十坑,我自己加的,哈哈,就是前面的js验证的时候,你不要头文件,怎么搞定这些事情,哈哈。是不是宝宝赢了。oh perfect,i like it。
75fad822a7b28d743ae6cf35a76963042cacc6d41bbb37262a98f745aa00fbf0
以上就是php微信公众账号开发遇到的五个坑总结的详细内容。