亚洲国产日韩欧美一区二区三区,精品亚洲国产成人av在线,国产99视频精品免视看7,99国产精品久久久久久久成人热,欧美日韩亚洲国产综合乱

首頁 微信小程式 微信開發(fā) php微信公眾帳號(hào)開發(fā)遇到的五個(gè)坑總結(jié)

php微信公眾帳號(hào)開發(fā)遇到的五個(gè)坑總結(jié)

Mar 21, 2017 pm 03:54 PM

這篇文章主要為大家詳細(xì)介紹了php微信公眾帳號(hào)開發(fā)之五個(gè)坑,具有一定的參考價(jià)值,有興趣的小伙伴們可以參考一下

##菜單回覆是需要處理XML文件的,我們根據(jù)微信傳回的XML文件,可以得到每個(gè)微信用戶相對(duì)於微信公眾號(hào)的唯一識(shí)別。微信公眾平臺(tái)的機(jī)制簡(jiǎn)單的將就是我們自己輸出固定格式的xml文件,然後微信APP負(fù)責(zé)解析,得到我們想要的信息,然後對(duì)信息統(tǒng)一處理。?

第六坑,如果你看微信文檔,那麼,絕對(duì)坑死你,上圖。這裡的ToUserName和FromUserName一定特麼的要分清楚了,記住,千萬不要寫反了,用戶對(duì)於微信而言是A→B,那麼微信對(duì)於用戶就是反著來的,貌似現(xiàn)在應(yīng)該說清楚了。

php微信公眾帳號(hào)開發(fā)遇到的五個(gè)坑總結(jié)


/// <summary>
 /// 接收微信發(fā)送的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))
  { 

  //封裝請(qǐng)求類
  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")//關(guān)注類型
    {
    WxXmlModel.EventKey = rootElement.SelectSingleNode("EventKey") == null ? "" : rootElement.SelectSingleNode("EventKey").InnerText;
    }
    break;
   default:
    break;
   }
  }
  ResponseXML(WxXmlModel);//回復(fù)消息
  }

 

 }
 catch (Exception ee)
 {
  //記錄錯(cuò)誤日志
 }
 }

 /// <summary>
 /// 回復(fù)消息
 /// </summary>
 /// <param name="WxXmlModel"></param>
 private void ResponseXML(WxXmlModel WxXmlModel)
 {
 string XML = "";
 switch (WxXmlModel.MsgType)
 {
  case "text"://文本回復(fù)
  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
  {
   //業(yè)務(wù)處理
  }
  else
  {
   XML = ResponseMessage.ReText(WxXmlModel.FromUserName, WxXmlModel.ToUserName, "/:rose農(nóng)場(chǎng)大數(shù)據(jù)歡迎你!/:rose");

  }
  break;
  case "event":
  switch (WxXmlModel.Event.ToLower())
  {
   case "subscribe":
   if (string.IsNullOrEmpty(WxXmlModel.EventKey))
   {
    XML = ResponseMessage.ReText(WxXmlModel.FromUserName, WxXmlModel.ToUserName, "關(guān)注成功!/:rose");

   }
   else
   {
    XML = ResponseMessage.SubScanQrcode(WxXmlModel.FromUserName, WxXmlModel.ToUserName, WxXmlModel.EventKey);//掃描帶參數(shù)二維碼先關(guān)注后推送事件
   }
   break;
   case "scan":
   XML = ResponseMessage.ScanQrcode(WxXmlModel.FromUserName, WxXmlModel.ToUserName, WxXmlModel.EventKey);//掃描帶參數(shù)二維碼已關(guān)注 直接推送事件
   break;
   case "click"://處理單擊事件
   if (WxXmlModel.EventKey == "p1")
   {
    //自己的業(yè)務(wù)邏輯
   }
   else
   {
    //自己的業(yè)務(wù)邏輯
   }
   break;
   case "unsubscribe"://取消關(guān)注
   break;
  }
  break;
  default://默認(rèn)回復(fù)
  break;
 }
 Response.Write(XML);//輸出組織的XML信息

 }

這就是選單的訊息處理,不明真相的群眾貌似會(huì)問那個(gè)所謂的ResponseMessage到底有幾個(gè)意思呢, OK,我已經(jīng)無力吐槽我這三天研究出來的微信公共平臺(tái)的東西了。?


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 "關(guān)鍵字":
  XML = ReText(FromUserName, ToUserName, "關(guān)鍵詞回復(fù)測(cè)試——興農(nóng)豐華:" + key);
  break;
  case "單圖文":
  XML = ReArticle(FromUserName, ToUserName, "測(cè)試標(biāo)題", "測(cè)試詳情——興農(nóng)豐華:" + key, "http://www.xnfhtech.com/templets/boze/images/20120130083143544.gif", "http://www.xnfhtech.com/");
  break;
  default:
  XML = ReText(FromUserName, ToUserName, "無對(duì)應(yīng)關(guān)鍵字——興農(nóng)豐華:" + key);
  break;
 }
 return XML;

 }

 /// <summary>
 /// 未關(guān)注掃描帶參數(shù)二維碼
 /// </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>
 /// 已關(guān)注掃描帶參數(shù)二維碼
 /// </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 回復(fù)方式
 /// <summary>
 /// 回復(fù)文本
 /// </summary>
 /// <param name="FromUserName">發(fā)送給誰(openid)</param>
 /// <param name="ToUserName">來自誰(公眾賬號(hào)ID)</param>
 /// <param name="Content">回復(fù)類型文本</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>";//發(fā)送給誰(openid),來自誰(公眾賬號(hào)ID)
 XML += "<CreateTime>" + CommonMethod.ConvertDateTimeInt(DateTime.Now) + "</CreateTime>";//回復(fù)時(shí)間戳
 XML += "<MsgType><![CDATA[text]]></MsgType>";//回復(fù)類型文本
 XML += "<Content><![CDATA[" + Content + "]]></Content><FuncFlag>0</FuncFlag></xml>";//回復(fù)內(nèi)容 FuncFlag設(shè)置為1的時(shí)候,自動(dòng)星標(biāo)剛才接收到的消息,適合活動(dòng)統(tǒng)計(jì)使用
 return XML;

 }
 

 /// <summary>
 /// 回復(fù)單圖文
 /// </summary>
 /// <param name="FromUserName">發(fā)送給誰(openid)</param>
 /// <param name="ToUserName">來自誰(公眾賬號(hào)ID)</param>
 /// <param name="Title">標(biāo)題</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>";//發(fā)送給誰(openid),來自誰(公眾賬號(hào)ID)
 XML += "<CreateTime>" + CommonMethod.ConvertDateTimeInt(DateTime.Now) + "</CreateTime>";//回復(fù)時(shí)間戳
 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>
 /// 多圖文回復(fù)
 /// </summary>
 /// <param name="FromUserName">發(fā)送給誰(openid)</param>
 /// <param name="ToUserName">來自誰(公眾賬號(hào)ID)</param>
 /// <param name="ArticleCount">圖文數(shù)量</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>";//發(fā)送給誰(openid),來自誰(公眾賬號(hào)ID)
 XML += "<CreateTime>" + CommonMethod.ConvertDateTimeInt(DateTime.Now) + "</CreateTime>";//回復(fù)時(shí)間戳
 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,加上自己的邏輯程式碼,是不是完美的實(shí)現(xiàn)了回應(yīng)??


第七坑,我真心不想數(shù)了,你確定這個(gè)回覆可以麼?說真的,寶寶不確定,因?yàn)槟銓懥酥嶂涝谀难e調(diào)用麼,我的乖乖,尼瑪,服務(wù)器驗(yàn)證通過就把回復(fù)加上去是最保險(xiǎn)的。我已經(jīng)沒有節(jié)操了。

接下來我們說什麼呢,我們就說說取得使用者資訊這個(gè)東西吧,因?yàn)槲覀冞@些東西一般都是基於H5頁面的。所以,就要用到之前我們配置的


php微信公眾帳號(hào)開發(fā)遇到的五個(gè)坑總結(jié)

這個(gè)東東,其實(shí)這個(gè)相對(duì)於前面的至少坑少了很多,真心的,寶寶就暫時(shí)不說他坑了。上個(gè)代碼吧。


//微信網(wǎng)頁授權(quán)2.0
public class Oauth2
{
 JavaScriptSerializer Jss = new JavaScriptSerializer();
 public Oauth2() { }
 

 /// <summary>
 /// 對(duì)頁面是否要用授權(quán)
 /// </summary>
 /// <param name="Appid">微信應(yīng)用id</param>
 /// <param name="redirect_uri">回調(diào)頁面</param>
 /// <param name="scope">應(yīng)用授權(quán)作用域snsapi_userinfo(不彈出授權(quán)頁面,直接跳轉(zhuǎn),只能獲取用戶openid),snsapi_userinfo (彈出授權(quán)頁面,可通過openid拿到昵稱、性別、所在地。并且,即使在未關(guān)注的情況下,只要用戶授權(quán),也能獲取其信息)</param>
 /// <returns>授權(quán)地址</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>
 /// 對(duì)頁面是否要用授權(quán)
 /// </summary>
 /// <param name="Appid">微信應(yīng)用id</param>
 /// <param name="redirect_uri">回調(diào)頁面</param>
 /// <param name="scope">應(yīng)用授權(quán)作用域snsapi_userinfo(不彈出授權(quán)頁面,直接跳轉(zhuǎn),只能獲取用戶openid),snsapi_userinfo (彈出授權(quán)頁面,可通過openid拿到昵稱、性別、所在地。并且,即使在未關(guān)注的情況下,只要用戶授權(quán),也能獲取其信息)</param>
 /// <returns>授權(quán)地址</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 此方法一般是不獲取用戶昵稱時(shí)候使用
 /// </summary>
 /// <param name="Appid"></param>
 /// <param name="Appsecret"></param>
 /// <param name="Code">回調(diào)頁面帶的code參數(shù)</param>
 /// <returns>微信用戶唯一標(biāo)識(shí)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換取獲取用戶信息(包括非關(guān)注用戶的)
 /// </summary>
 /// <param name="Appid"></param>
 /// <param name="Appsecret"></param>
 /// <param name="Code">回調(diào)頁面帶的code參數(shù)</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失敗,錯(cuò)誤碼:" + 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方法獲取信息

 }

}

我們需要呼叫的時(shí)候直接用裡面的方法,取得微信網(wǎng)頁授權(quán)即可,例如對(duì)於A控制器下面的B視圖要取得授權(quán),並且要取得使用者的相關(guān)訊息,那麼我們直接呼叫即可,如GetCodeUrl(appid, "http://" + Url + "/A/B", "snsapi_userinfo")


##在這裡我還是吐槽一下吧。


第八坑,

微信選單JSON的url拼接,裡面的前面不是加了js驗(yàn)證麼,so,特麼的,還是乖乖的加上http:/ /。
不過這裡授權(quán)之後,因?yàn)槭褂谜叩脑S多資訊我們都要用到,這就是H5頁面?zhèn)髦档膯栴},我在專案裡面用的是Session,直接寫一個(gè)公用方法,如果Session有值,則直接取值的。對(duì)於裡面的一些東東,我想說明一下,並不是所有的程式碼都要貼出來,我這邊的程式碼只是我個(gè)人認(rèn)為需要貼出來的。所以裡面的方法可能有大家看不到的,如果需要,可以留言本寶寶,謝謝。?

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; };

}

然後每次遇到需要取得資訊的頁面,我通常都是呼叫這個(gè)就可以了。?


基本上剩下的都是我們自己要處理的業(yè)務(wù)邏輯了,繼續(xù)說到坑吧。?


第九坑,

微信上傳圖片,坑的絕對(duì)不只是自己。對(duì)於這個(gè)寶寶真的信了,不管你信不信。特麼的圖片不能for循環(huán)上傳。當(dāng)然,這個(gè)只限蘋果機(jī)型,大Android還是沒有問題的。 前面說到了JS安全驗(yàn)證的問題,這裡就是呼叫這些個(gè)驗(yàn)證,請(qǐng)求一些應(yīng)該的權(quán)限,然後取得圖片資訊等等。?

php微信公眾帳號(hào)開發(fā)遇到的五個(gè)坑總結(jié)放心好了,寶寶現(xiàn)在都是上圖說話,沒圖說個(gè)小弟弟呀。 。 。 。 。?


我們繼續(xù)回來看程式碼。?


先來個(gè)處理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 驗(yàn)證JsApi權(quán)限配置
 /// <summary>
 /// 獲取JsApi權(quán)限配置的數(shù)組/四個(gè)參數(shù)
 /// </summary>
 /// <param name="Appid">應(yīng)用id</param>
 /// <param name="Appsecret">密鑰</param>
 /// <returns>json格式的四個(gè)參數(shù)</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();//生成簽名的時(shí)間戳
 string nonceStr = CommonMethod.GetRandCode(16);//生成簽名的隨機(jī)串
 string url = System.Web.HttpContext.Current.Request.Url.AbsoluteUri.ToString();//當(dāng)前的地址
 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(" ", "");

 }

}

然後看具體呼叫。


後臺(tái)程式碼其實(shí)很簡(jiǎn)單的,直接輸出設(shè)定文件,然後前臺(tái)js直接呼叫即可。?

#

JsApi jsApi = new JsApi();
string config = jsApi.GetJsApiInfo(appId, appSecret);
ViewBag.config = config;

前臺(tái)代碼,其實(shí)也不難,這個(gè)有官方的例子的。


<script type="text/javascript">
 wx.config(@Html.Raw(ViewBag.config));//后臺(tái)傳遞的微信配置文件
 wx.ready(function () {
 $("#avatar").click(function () {
  wx.chooseImage({
  count: 1, // 圖片數(shù)量 默認(rèn)9
  sizeType: [&#39;compressed&#39;], // 可以指定是原圖還是壓縮圖,默認(rèn)二者都有&#39;original&#39;,
  sourceType: [&#39;album&#39;, &#39;camera&#39;], // 可以指定來源是相冊(cè)還是相機(jī),默認(rèn)二者都有
  success: function (res) {
   var localIds = res.localIds; // 返回選定照片的本地ID列表,localId可以作為img標(biāo)簽的src屬性顯示圖片
   wx.uploadImage({
   localId: &#39;&#39; + localIds,
   isShowProgressTips: 1,
   success: function (res) {
    serverId = res.serverId;
    getWxPhoto(serverId);

   }

   });

  }

  });

 });

 });

 wx.error(function (res) {
 alert("接口驗(yàn)證失敗,詳細(xì)信息:\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(&#39;src&#39;, ".." + data.result);
  $("#hed_pic").attr(&#39;alt&#39;, "avatarImg");

  }

 });

 }

</script>

OK,后臺(tái)方法其實(shí)也很簡(jiǎn)單,就是一個(gè)二進(jìn)制文件處理,不對(duì),簡(jiǎn)單個(gè)蛋蛋,特么的,因?yàn)槁窂降膯栴},坑了寶寶一個(gè)小時(shí),特么的。還有這里建議,等微信圖片下載完成之后再給前臺(tái)加載圖片,保證每一個(gè)圖片都加載完成,保證后臺(tái)的圖片的上傳完成。


/// <summary>
/// 下載多媒體文件
/// </summary>
/// <param name="userName">公眾號(hào)</param>
/// <param name="mediaId">媒體ID</param>
/// <param name="data">返回下載是否成功</param>
/// <param name="types">添加的圖片類型</param>
/// <returns>返回多媒體文件數(shù)據(jù);如果下載失敗,返回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, "從微信服務(wù)器下載多媒體文件失敗。");
 }

 }
 else
 errorMessage = new ErrorMessage(ErrorMessage.ExceptionCode, "從微信服務(wù)器下載多媒體文件失敗。");
 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); //將文件指針設(shè)置到文件開
 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>
/// 判斷目標(biāo)字節(jié)數(shù)組是否位于源字節(jié)數(shù)組的開始
/// </summary>
/// <param name="source">源字節(jié)數(shù)組</param>
/// <param name="target">目標(biāo)字節(jié)數(shù)組</param>
/// <returns>返回目標(biāo)字節(jié)數(shù)組是否位于源字節(jié)數(shù)組的開始</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;

}

是不是以為這就算完事了,我的乖乖,頭像上傳了,微信攝像頭也特么該調(diào)用的調(diào)用了,寶寶好幸福,寶寶也是牛人一個(gè)了,記住前面的東東,寶寶還沒有說坑呢。
來重復(fù)我們的第九個(gè)坑,特么的,你JS寫個(gè)for循環(huán)要是能循環(huán)把圖片上傳到后臺(tái),寶寶也服氣,真的,寶寶服氣。

直接說吧,最后我自己想了下,也和隊(duì)友討論了下,可能是因?yàn)槲⑿庞惺裁打?yàn)證,導(dǎo)致之后一張圖片上傳成功之后,才能進(jìn)行一張,但是我們Iphone就是特么的特例,大Android沒用問題的,就是Iphone有了問題,而且問題不小,上傳四張圖片吧,老特么是最后一張,最后,找到了萬能的網(wǎng)友,感謝你,不過寶寶已經(jīng)忘記了在哪里找到的了,尷尬了。。。。。。。。。。。


<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: &#39;&#39; + 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(&#39;<li><p class="imgbox"><img src="/static/imghw/default1.png"  data-src="/img/cechanadd.png"  class="lazy"   id="picture&#39; + i + &#39;" alt="" /></p></li>&#39;);

    $("#picture" + i).attr(&#39;src&#39;, data.result);
    $("#picPath").append(&#39;<input value=&#39; + data.result + &#39; type="hidden" id="picurl&#39; + i + &#39;" class="picclass" />&#39;);

    i++;

    if (i == resurl.localIds.length - 1) {

     $("#picPath").append(&#39;<li><p class="imgbox"><img src="/static/imghw/default1.png"  data-src="/img/cechanadd.png"  class="lazy"   id="picture" alt="" /></p></li>&#39;);

    }

    up(resurl);
    }
   });

   }
  });
  } else {

  i = 0;
  }

 }

 

 
 //上傳圖片
 wx.config(@Html.Raw(ViewBag.config));
 wx.ready(function () {
  $("#picPath").click(function () {
  wx.chooseImage({
   count: 3, // 默認(rèn)9
   sizeType: [&#39;compressed&#39;], // 可以指定是原圖還是壓縮圖,默認(rèn)二者都有&#39;original&#39;,
   sourceType: [&#39;album&#39;, &#39;camera&#39;], // 可以指定來源是相冊(cè)還是相機(jī),默認(rèn)二者都有
   success: function (resu) {
   var localIds = resu.localIds; // 返回選定照片的本地ID列表,localId可以作為img標(biāo)簽的src屬性顯示圖片
   if (localIds.indexOf("wxlocalresource") != -1) {    
   localIds = localIds.replace("wxlocalresource", "wxLocalResource");
   }
 
   @(index += 1)
   if (localIds != &#39;&#39;) {
    $("#picPath").html("");
   var sear = new RegExp(&#39;,&#39;);
    if (sear.test(localIds)) {
    up(resu);
    }

    else {
    $("#picPath").append(&#39; <li><p class="imgbox"><img src="/static/imghw/default1.png"  data-src="/img/cechanadd.png"  class="lazy"   id="picture&#39; + &#39;@index&#39; + &#39;" alt="" " /></p></li>&#39;);
    $("#picture" + "@index").attr(&#39;src&#39;, localIds);
    // 上傳照片
    wx.uploadImage({
     localId: &#39;&#39; + 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(&#39;<input value=&#39; + data.result + &#39; type="hidden" id="picurl&#39; + @index + &#39;" class="picclass" />&#39;);

      $("#picPath").append(&#39;<li><p class="imgbox"><img src="/static/imghw/default1.png"  data-src="/img/cechanadd.png"  class="lazy"   id="picture" alt="" /></p></li>&#39;);
      }
     });

    }
    });
    }
    // $("#picPath").append(&#39;<li><p class="imgbox"><img src="/static/imghw/default1.png"  data-src="/img/cechanadd.png"  class="lazy"   id="picture" alt="" /></p></li>&#39;);

   }
   }
  });
  });
 });
 wx.error(function (res) {
  alert("接口驗(yàn)證失敗,詳細(xì)信息:\n" + JSON.stringify(res));
 });
 </script>

請(qǐng)記住,遞歸就特么可以了。

說到這里,寶寶已經(jīng)不想多說什么了,特么的產(chǎn)品你能不能不裝逼,你特么見過那個(gè)微信能回復(fù)一個(gè)信息直接跳轉(zhuǎn)網(wǎng)頁的,你咋不去屎呢,聯(lián)想到前幾天大阿里的月餅時(shí)間,突然感覺我們程序員挺悲劇的,成功的都是特么的產(chǎn)品,然后出問題的都是我們程序員的鍋?試問一下,這個(gè)鍋真心我們程序員該背么。

算了,還是不吐槽了,已經(jīng)無力了。。。。寶寶92年降臨,現(xiàn)在確實(shí)82年的皮膚呀,唉,寶寶累了,真的。

順便給點(diǎn)H5頁面的建議吧。比如當(dāng)點(diǎn)擊返回鍵的時(shí)候,我們需要刷新頁面的時(shí)候,就是所謂的判斷頁面要不要刷新,這里有很多種方法,但是微信里面寶寶還是覺得這么干靠譜。


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

還有,那個(gè)微信執(zhí)行完成之后想直接退出當(dāng)前界面進(jìn)入微信公眾號(hào)界面的,直接調(diào)用微信的一個(gè)內(nèi)置的方法即可。記得寫到<script></script>里面。?

WeixinJSBridge.call('closeWindow'); //這是微信關(guān)閉當(dāng)前網(wǎng)頁

這么自信的以為自己搞定了所有,你跑呀,你要跑起來,嗯哼,別不服氣。?

微信公眾賬號(hào)指第十坑,我自己加的,哈哈,就是前面的JS驗(yàn)證的時(shí)候,你不要頭文件,怎么搞定這些事情,哈哈。是不是寶寶贏了。Oh? perfect,I like it。

以上是php微信公眾帳號(hào)開發(fā)遇到的五個(gè)坑總結(jié)的詳細(xì)內(nèi)容。更多資訊請(qǐng)關(guān)注PHP中文網(wǎng)其他相關(guān)文章!

本網(wǎng)站聲明
本文內(nèi)容由網(wǎng)友自願(yuàn)投稿,版權(quán)歸原作者所有。本站不承擔(dān)相應(yīng)的法律責(zé)任。如發(fā)現(xiàn)涉嫌抄襲或侵權(quán)的內(nèi)容,請(qǐng)聯(lián)絡(luò)admin@php.cn

熱AI工具

Undress AI Tool

Undress AI Tool

免費(fèi)脫衣圖片

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅(qū)動(dòng)的應(yīng)用程序,用於創(chuàng)建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費(fèi)的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費(fèi)的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強(qiáng)大的PHP整合開發(fā)環(huán)境

Dreamweaver CS6

Dreamweaver CS6

視覺化網(wǎng)頁開發(fā)工具

SublimeText3 Mac版

SublimeText3 Mac版

神級(jí)程式碼編輯軟體(SublimeText3)

熱門話題

Laravel 教程
1597
29
PHP教程
1488
72