php微信公众账号开发遇到的五个坑总结

互联网 17-3-21
这篇文章主要为大家详细介绍了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     }

第七坑,我真心不想计数了,你确定这个回复可以么?说真的,宝宝不确定,因为你写了之后知道在哪里调用么,我的乖乖,尼玛,服务器验证通过就把回复加上去是最保险的。我已经没有节操了。

这个东东,其实这个相对于前面的至少坑少了很多,真心的,宝宝就暂时不说他坑了。上个代码吧。

//微信网页授权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方法获取信息     }    }

第八坑,微信菜单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安全验证的问题,这里就是调用这些个验证,请求一些应该的权限,然后获取图片信息等等。

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>

顺便给点H5页面的建议吧。比如当点击返回键的时候,我们需要刷新页面的时候,就是所谓的判断页面要不要刷新,这里有很多种方法,但是微信里面宝宝还是觉得这么干靠谱。

<script type="text/javascript">   if (window.name != "hasLoad") {   location.reload();   window.name = "hasLoad";   } else {   window.name = "";   }  </script>

还有,那个微信执行完成之后想直接退出当前界面进入微信公众号界面的,直接调用微信的一个内置的方法即可。记得写到<script></script>里面。

WeixinJSBridge.call('closeWindow'); //这是微信关闭当前网页

微信公众账号指第十坑,我自己加的,哈哈,就是前面的JS验证的时候,你不要头文件,怎么搞定这些事情,哈哈。是不是宝宝赢了。Oh perfect,I like it。

<script src="http://res.wx.qq.com/open/js/jweixin-1.0.0.js"></script>

以上就是php微信公众账号开发遇到的五个坑总结的详细内容,更多内容请关注技术你好其它相关文章!

来源链接:
免责声明:
1.资讯内容不构成投资建议,投资者应独立决策并自行承担风险
2.本文版权归属原作所有,仅代表作者本人观点,不代表本站的观点或立场
标签: php 微信开发
上一篇:php获取远程图片并下载保存到本地的方法分析 下一篇:PHP微信开发之有道翻译实例代码

相关资讯