이 글에서는 주로 PHP WeChat 공개 계정 개발의 5가지 함정을 자세히 소개하고 있습니다. 관심 있는 친구는
메뉴를 참조하세요. XML 파일 . WeChat에서 반환한 XML 파일을 기반으로 WeChat 공식 계정과 관련된 각 WeChat 사용자의 고유 식별자를 얻을 수 있습니다. WeChat 공개 플랫폼의 메커니즘은 단순히 우리가 고정 형식의 XML 파일을 직접 출력한 다음 WeChat 앱이 이를 구문 분석하고 원하는 정보를 얻은 다음 통합된 방식으로 정보를 처리하는 것입니다.
여섯 번째 구덩이, 위챗 문서를 보면 위 사진처럼 무조건 죽인다. 여기서 ToUserName과 FromUserName은 명확하게 구분되어야 합니다. 절대 거꾸로 쓰지 마세요. WeChat의 경우 사용자가 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는 다음을 의미합니다. 지난 3일 동안 조사한 WeChat 공개 플랫폼에 대해 더 이상 불평할 수 없습니다.
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 }
좋아, 자신만의 로직 코드로 응답이 완벽하게 구현되었나요?
일곱 번째 구덩이 정말 더 이상 셀 수 없어요, 이 답글 괜찮을까요? 솔직히 말해서 잘 모르겠습니다. 작성한 후 어디로 전화해야 할지 아시나요? 젠장, 서버가 확인을 통과한 후에 응답을 추가하는 것이 가장 안전합니다. 나는 더 이상 도덕이 없습니다.
다음에는 사용자 정보 획득에 대해 이야기해 보겠습니다. 우리의 이러한 정보는 일반적으로 H5 페이지를 기반으로 하기 때문입니다. 따라서 이전에 구성한
항목을 사용해야 합니다. 실제로 이전 항목에 비해 함정이 훨씬 적습니다. 진심으로, 지금은 그냥 두겠습니다. 그가 속았다는 것은 말할 것도 없습니다. 몇 가지 코드를 넣어 보겠습니다. <… 컨트롤러를 만들고 사용자 관련 정보를 얻은 다음 GetCodeUrl(appid, "http://" + Url + "/A/B", "snsapi_userinfo")
<🎜와 같이 직접 호출할 수 있습니다. >여기서 아직 불평하자.
8번째 피트,
//微信网页授权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方法获取信息 } }
기본적으로 나머지는 우리가 스스로 처리해야 하는 비즈니스 로직입니다. 계속해서 함정에 대해 이야기해 보겠습니다.
아홉 번째 함정,
앞서 JS 보안 확인 문제에 대해 언급했습니다. 여기서는 이러한 확인을 호출하고 적절한 권한을 요청한 다음 이미지 정보를 얻는 등의 작업을 수행합니다.
걱정하지 마세요. 위 그림에서 아기가 말하는 것은 남동생 이야기가 아닙니다. . . . .
계속해서 코드를 살펴보겠습니다.
먼저 Json을 다루겠습니다
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; }; }
. 그런 다음 특정 호출을 살펴보세요.
백그라운드 코드는 실제로 매우 간단합니다. 구성 파일을 직접 출력한 다음 프런트엔드 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>
还有,那个微信执行完成之后想直接退出当前界面进入微信公众号界面的,直接调用微信的一个内置的方法即可。记得写到<script></script>里面。
WeixinJSBridge.call('closeWindow'); //这是微信关闭当前网页
这么自信的以为自己搞定了所有,你跑呀,你要跑起来,嗯哼,别不服气。
微信公众账号指第十坑,我自己加的,哈哈,就是前面的JS验证的时候,你不要头文件,怎么搞定这些事情,哈哈。是不是宝宝赢了。Oh perfect,I like it。
위 내용은 PHP WeChat 공개 계정 개발 시 직면하게 되는 5가지 함정 요약의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!