php微信公众账号开发之五个坑(二)

前端之家收集整理的这篇文章主要介绍了php微信公众账号开发之五个坑(二)前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

说到微信公众账号的几个坑,前面五个,已经说到菜单,宝宝继续往下赘述了。可惜,还不知道宝宝的宝宝到底是不是心疼宝宝呢,完了,我凌乱了。。。

回到正题,我们就不吐槽其他的了,上一篇说到微信的菜单了,那么,我们现在说说菜单回复等等的吧。

菜单回复是需要处理XML文件的,我们根据微信返回的XML文件,可以得到用户相对于微信公众号的唯一标识。微信公众平台的机制简单的将就是我们自己输出固定格式的xml文件,然后微信APP负责解析,得到我们想要的信息,然后对信息统一处理。

第六坑,

如果你看微信文档,那么,绝对坑死你,上图。这里的ToUserName和FromUserName一定特么的要分清楚了,记住,千万不要写反了,用户对于微信而言是A→B,那么微信对于用户就是反着来的,貌似现在应该说清楚了。

/// 接收微信发送的XML消息并且解析 /// private void ReceiveXml() { try { Stream requestStream = System.Web.HttpContext.Current.Request.InputStream; byte[] requestByte = new byte[requestStream.Length]; requestStream.Read(requestByte,(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)
{
//记录错误日志
}
}

///


/// 回复消息
///

/// <param name="WxXmlModel">
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,"关注成功!/:rose");

}
else
{
XML = ResponseMessage.SubScanQrcode(WxXmlModel.FromUserName,WxXmlModel.EventKey);//扫描带参数二维码先关注后推送事件
}
break;
case "scan":
XML = ResponseMessage.ScanQrcode(WxXmlModel.FromUserName,WxXmlModel.EventKey);//扫描带参数二维码已关注 直接推送事件
break;
case "click"://处理单击事件
if (WxXmlModel.EventKey == "p1")
{
//自己的业务逻辑
}
else
{
//自己的业务逻辑
}
break;
case "unsubscribe"://取消关注
break;
}
break;
default://默认回复
break;
}
Response.Write(XML);//输出组织的XML信息

}

这就是菜单的信息处理,不明真相的群众貌似会问那个所谓的ResponseMessage到底有几个意思呢,OK,我已经无力吐槽我这三天研究出来的微信公共平台的东西了。

{

region 接收的类型

///


/// 接收文本
///

/// <param name="FromUserName">
/// <param name="ToUserName">
/// <param name="Content">
///
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,"测试标题","测试详情——兴农丰华:" + key,"http://www.xnfhtech.com/templets/boze/images/20120130083143544.gif","http://www.xnfhtech.com/");
break;
default:
XML = ReText(FromUserName,"无对应关键字——兴农丰华:" + key);
break;
}
return XML;

}

///


/// 未关注扫描带参数二维码
///

/// <param name="FromUserName">
/// <param name="ToUserName">
/// <param name="EventKey">
///
public static string SubScanQrcode(string FromUserName,string EventKey)
{
return "";
}

///


/// 已关注扫描带参数二维码
///

/// <param name="FromUserName">
/// <param name="ToUserName">
/// <param name="EventKey">
///
public static string ScanQrcode(string FromUserName,string EventKey)
{
return "";
}

endregion

region 回复方式

///


/// 回复文本
///

/// <param name="FromUserName">发送给谁(openid)
/// <param name="ToUserName">来自谁(公众账号ID)
/// <param name="Content">回复类型文本
/// 拼凑的XML

public static string ReText(string FromUserName,string Content)
{
string XML = "<![CDATA[" + FromUserName + "]]><![CDATA[" + ToUserName + "]]>";//发送给谁(openid),来自谁(公众账号ID)
XML += "" + CommonMethod.ConvertDateTimeInt(DateTime.Now) + "";//回复时间戳
XML += "<![CDATA[text]]>";//回复类型文本
XML += "<![CDATA[" + Content + "]]>0
";//回复内容 FuncFlag设置为1的时候,自动星标刚才接收到的消息,适合活动统计使用
return XML;

}

///


/// 回复单图文
///

/// <param name="FromUserName">发送给谁(openid)
/// <param name="ToUserName">来自谁(公众账号ID)
/// <param name="Title">标题
/// <param name="Description">详情
/// <param name="PicUrl">图片地址
/// <param name="Url">地址
/// 拼凑的XML

public static string ReArticle(string FromUserName,string Title,string Description,string PicUrl,string Url)
{

string XML = "<![CDATA[" + FromUserName + "]]><![CDATA[" + ToUserName + "]]>";//发送给谁(openid),来自谁(公众账号ID)
XML += "" + CommonMethod.ConvertDateTimeInt(DateTime.Now) + "";//回复时间戳
XML += "<![CDATA[news]]><![CDATA[]]>1";
XML += "<![CDATA[" + Title + "]]><![CDATA[" + Description + "]]><![CDATA[" + PicUrl + "]]><![CDATA[" + Url + "]]>";
XML += "
0
";
return XML;

}

///


/// 多图文回复
///

/// <param name="FromUserName">发送给谁(openid)
/// <param name="ToUserName">来自谁(公众账号ID)
/// <param name="ArticleCount">图文数量
/// <param name="dtArticle">
///

public static string ReArticle(string FromUserName,int ArticleCount,System.Data.DataTable dtArticle)
{

string XML = "<![CDATA[" + FromUserName + "]]><![CDATA[" + ToUserName + "]]>";//发送给谁(openid),来自谁(公众账号ID)
XML += "" + CommonMethod.ConvertDateTimeInt(DateTime.Now) + "";//回复时间戳
XML += "<![CDATA[news]]><![CDATA[]]>" + ArticleCount + "";
foreach (System.Data.DataRow Item in dtArticle.Rows)

{
XML += "<![CDATA[" + Item["Title"] + "]]><![CDATA[" + Item["Description"] + "]]><![CDATA[" + Item["PicUrl"] + "]]><![CDATA[" + Item["Url"] + "]]>";
}
XML += "0";
return XML;

}

endregion

}

OK,加上自己的逻辑代码,是不是完美的实现了回复

第七坑,

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

接下来我们说什么呢,我们就说说获取用户信息这个东西吧,因为我们这些东西一般都是基于H5页面的。所以,就要用到之前我们配置的

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

///
/// 对页面是否要用授权
///

/// <param name="Appid">微信应用id
/// <param name="redirect_uri">回调页面
/// <param name="scope">应用授权作用域snsapi_userinfo(不弹出授权页面,直接跳转,只能获取用户openid),snsapi_userinfo (弹出授权页面,可通过openid拿到昵称、性别、所在地。并且,即使在未关注的情况下,只要用户授权,也能获取其信息)
/// 授权地址

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

///


/// 对页面是否要用授权
///

/// <param name="Appid">微信应用id
/// <param name="redirect_uri">回调页面
/// <param name="scope">应用授权作用域snsapi_userinfo(不弹出授权页面,直接跳转,只能获取用户openid),snsapi_userinfo (弹出授权页面,可通过openid拿到昵称、性别、所在地。并且,即使在未关注的情况下,只要用户授权,也能获取其信息)
/// 授权地址
public string GetCodeUrl(string Appid,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",scope,state);
}

///


/// 用code换取openid 此方法一般是不获取用户昵称时候使用
///

/// <param name="Appid">
/// <param name="Appsecret">
/// <param name="Code">回调页面带的code参数
/// 微信用户唯一标识openid
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",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();
}

///


///用code换取获取用户信息(包括非关注用户的)
///

/// <param name="Appid">
/// <param name="Appsecret">
/// <param name="Code">回调页面带的code参数
/// 获取用户信息(json格式)

public string GetUserInfo(string Appid,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",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","");

}

}

///


/// 通过openId获取用户信息
///

/// <param name="accesstoken">
/// <param name="openid">
///
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有值,则直接取值的。对于里面的一些东东,我想说明一下,并不是所有的代码都要贴出来,我这边的代码只是我个人认为需要贴出来的。所以里面的方法可能有大家看不到的,如果需要,可以留言本宝宝,谢谢。

{

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的

{
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权限配置

///


/// 获取JsApi权限配置的数组/四个参数
///

/// <param name="Appid">应用id
/// <param name="Appsecret">密钥
/// json格式的四个参数
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直接调用即可。

前台代码,其实也不难,这个有官方的例子的。

后台传递的微信配置文件 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");

}

});

}

OK,后台方法其实也很简单,就是一个二进制文件处理,不对,简单个蛋蛋,特么的,因为路径的问题,坑了宝宝一个小时,特么的。还有这里建议,等微信图片下载完成之后再给前台加载图片,保证每一个图片都加载完成,保证后台图片上传完成。

/// 下载多媒体文件 /// /// /// /// /// 添加的图片类型 /// 返回多媒体文件数据;如果下载失败,返回null。 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,pReadByte.Length);
}
catch

{
return false;
}
finally

{
if (pFileStream != null)

pFileStream.Close();

}

return true;

}
///


/// 判断目标字节数组是否位于源字节数组的开始
///

/// <param name="source">源字节数组
/// <param name="target">目标字节数组
/// 返回目标字节数组是否位于源字节数组的开始

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有了问题,而且问题不小,上传四张图片吧,老特么是最后一张,最后,找到了万能的网友,感谢你,不过宝宝已经忘记了在哪里找到的了,尴尬了。。。。。。。。。。。

<div class="jb51code">
<pre class="brush:js;">
<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],success: function (res) {
// alert("res.serverId:" + res.serverId);
mediaId = res.serverId;
$.ajax({
async: false,data: { mediaId: mediaId,success: function (data) {
$("#picPath").append('

  • <div class="imgBox">
  • ');

    $("#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><div class="img<a href="https://www.jb51.cc/tag/Box/" target="_blank" class="keywords">Box</a>"&gt;<img src="/img/cechanadd.png" id="picture" alt="" /></div></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'],// 可以指定来源是相册还是相机,默认二者都有
    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><div class="img<a href="https://www.jb51.cc/tag/Box/" target="_blank" class="keywords">Box</a>"&gt;<img src="/img/cechanadd.png" id="picture' + '@index' + '" alt="" " /></div></li>');
    $("#picture" + "@index").attr('src',localIds);
    // <a href="https://www.jb51.cc/tag/shangchuan/" target="_blank" class="keywords">上传</a>照片
    wx.uploadImage({
     localId: '' + localIds,success: function (res) {
     mediaId = res.serverId;
    
     $.ajax({
      async: false,success: function (data) {
    
      $("#picPath").append('<input value=' + data.result + ' type="hidden" id="picurl' + @index + '" class="picclass" />');
    
      $("#picPath").append('<li><div class="img<a href="https://www.jb51.cc/tag/Box/" target="_blank" class="keywords">Box</a>"&gt;<img src="/img/cechanadd.png" id="picture" alt="" /></div></li>');
      }
     });
    
    }
    });
    }
    // $("#picPath").append('<li><div class="img<a href="https://www.jb51.cc/tag/Box/" target="_blank" class="keywords">Box</a>"&gt;<img src="/img/cechanadd.png" id="picture" alt="" /></div></li>');

    }
    }
    });
    });
    });
    wx.error(function (res) {
    alert("接口验证失败,详细信息:\n" + JSON.stringify(res));
    });

    请记住,递归就特么可以了。

    说到这里,宝宝已经不想多说什么了,特么的产品你能不能不装逼,你特么见过那个微信能回复一个信息直接跳转网页的,你咋不去屎呢,联想到前几天大阿里的月饼时间,突然感觉我们程序员挺悲剧的,成功的都是特么的产品,然后出问题的都是我们程序员的锅?试问一下,这个锅真心我们程序员该背么。

    算了,还是不吐槽了,已经无力了。。。。宝宝92年降临,现在确实82年的皮肤呀,唉,宝宝累了,真的。

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

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

    关闭当前网页

    这么自信的以为自己搞定了所有,你跑呀,你要跑起来,嗯哼,别不服气。

    微信公众账号指

    第十坑

    ,我自己加的,哈哈,就是前面的JS验证的时候,你不要头文件,怎么搞定这些事情,哈哈。是不是宝宝赢了。Oh perfect,I like it。

    这个东西一定不能忘记哈。

    以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持编程之家。

    原文链接:https://www.f2er.com/php/19015.html

    猜你在找的PHP相关文章