至尊技术网 - 微信小程序 https://www.zzwws.cn/tag/%E5%BE%AE%E4%BF%A1%E5%B0%8F%E7%A8%8B%E5%BA%8F/ 利用node.js反编译脚本获得微信小程序源码 https://www.zzwws.cn/archives/6408/ 2023-06-19T15:17:00+08:00 一、node.js运行环境1、安装node.js地址:https://nodejs.org/zh-cn/安装后在控制台输入:node -v, 如果显示版本号则安装成功2、安装npm一般情况下nodejs安装好后自带npm可以在控制台输入:npm -v, 如果显示版本号则安装成功。二、下载反编译脚本https://gitee.com/moduo_412/wxappUnpacker三、安装模拟器下载夜神模拟器或其他模拟器安装RE文件管理器,使用解密工具可以不用安装模拟器,找到__APP__.wxapkg,不确定是哪个目录可以把当前目录删除,再重新打开小程序四、在本地找到小程序源文件包/data/data/com.tencent.mm/MicroMsg/一串32位的16进制字符串文件夹/appbrand/pkg/小程序源文件包这个目录下就是你的小程序源文件了,小程序格式就是wxapkg,根据时间找到源文件包压缩后发送到电脑五、反编译解包1、打开nodejs命令窗口2、用cd命令进入反编译脚本根目录下3、在node命令窗口中依次安装如下// 安装 npm install // 安装依赖 npm install esprima npm install css-tree npm install cssbeautify npm install vm2 npm install uglify-es npm install js-beautify 4、安装好依赖之后,就是最后一步了,反编译 .wxapkg 文件在当前目录下输入命令:node wuWxapkg.js _163200311_32.wxapkg_163200311_32.wxapkg是你需要反编译的源文件,输入前几个字符可以按tab键补全在当前目录找到_163200311_32文件夹(如果不是想要的,请换一个.wxapkg文件):5、报错处理Cannot find module 'xxx' 模块未安装运行命令:npm install xxx如果这种错误,请重新换一个.wxapkg文件执行脚本中可能会出现以下报错1、修改wuWxss.js文件31行if (!importCnt[id]) importCnt[id] = 1, statistic(pureData[id]); // 替换为 if(!importCnt[id]){ if(pureData){ importCnt[id]=1; statistic(pureData[id]); } } 2、修改wuWxss.js文件243行pureData = vm.run(code + "\n_C"); // 替换为 pureData = vm.run(code + "}"); 微信小程序的事件冒泡和捕获 https://www.zzwws.cn/archives/6363/ 2022-09-07T14:10:00+08:00 事件冒泡当一个组件上的事件被触发后,该事件会向父节点传递。bind事件名<text>事件的冒泡</text> <view class="one" bindtap="handlerOne">one <view class="two" bindtap="handlerTwo">two <view class="three" bindtap="handlerThree">three</view> </view> </view> 阻止事件冒泡catch事件名<text>事件的冒泡</text> <view class="one" bindtap="handlerOne">one <view class="two" catchtap="handlerTwo">two <view class="three" bindtap="handlerThree">three</view> </view> </view> 事件捕获捕获阶段位于冒泡阶段之前,且在捕获阶段中,事件到达节点的顺序与冒泡阶段恰好相反。需要在捕获阶段监听事件时,可以采用:capture-bind:事件名<view class="one" capture-bind:tap="handlerOne">one <view class="two" capture-bind:tap="handlerTwo">two <view class="three" capture-bind:tap="handlerThree">three</view> </view> </view> 阻止事件捕获capture-catch:事件名capture-catch关键字,后者将中断捕获阶段和取消冒泡阶段。<view class="one" capture-bind:tap="handlerOne">one <view class="two" capture-catch:tap="handlerTwo">two <view class="three" capture-bind:tap="handlerThree">three</view> </view> </view> 微信小程序长按事件 https://www.zzwws.cn/archives/6347/ 2022-07-15T11:28:00+08:00 <view bindtouchstart="touchstart" bindtouchend="touchend">123456</view> //touch start touchstart: function(e) { this.startTime = e.timeStamp; console.log(this.startTime) }, //touch end touchend: function(e) { this.endTime = e.timeStamp; console.log(this.endTime) console.log("endTime - startTime = " + (this.endTime-this.startTime)); if (this.endTime - this.startTime>600){ console.log('长按') } } 微信小程序接入微信支付 https://www.zzwws.cn/archives/6332/ 2022-03-02T16:07:00+08:00 获取openid参考微信授权登录微信小程序MD5加密(支持中文):https://zhizun.lanzouy.com/inF7G00vonmbpay.jsimport util from '../../utils/util.js' const md5 = require('../../utils/md5.js'); Page({ /** * 页面的初始数据 */ data: { id: '' }, /** * 生命周期函数--监听页面加载 */ onLoad: function () { }, submit(){ this.setData({id: 1}) this.unitedPayRequest('openid') }, /*统一支付接口*/ unitedPayRequest: function(openid){ var that = this; //统一支付签名 var accountInfo = wx.getAccountInfoSync(); var appid = accountInfo.miniProgram.appId;//appid必填 var body = '';//商品名必填 var mch_id = '';//商户号必填 var key = ''; //商户key必填,在商户后台获得 var out_trade_no = '';//自定义订单号必填 var nonce_str = util.randomString();//随机字符串,不长于32位。 var total_fee = parseInt(0.01 * 100); //价格,这是一分钱 var notify_url = 'http://localhost/notify_url.php';//通知地址必填 var trade_type = "JSAPI"; var unifiedPayment = 'appid=' + appid + '&body=' + body + '&mch_id=' + mch_id + '&nonce_str=' + nonce_str + '&notify_url=' + notify_url + '&openid=' + openid + '&out_trade_no=' + out_trade_no + '&total_fee=' + total_fee + '&trade_type=' + trade_type + '&key=' + key; console.log("unifiedPayment", unifiedPayment); var sign = md5.md5(unifiedPayment).toUpperCase(); console.log("签名md5", sign); //封装统一支付xml参数 var formData = "<xml>"; formData += "<appid>" + appid + "</appid>"; formData += "<body>" + body + "</body>"; formData += "<mch_id>" + mch_id + "</mch_id>"; formData += "<nonce_str>" + nonce_str + "</nonce_str>"; formData += "<notify_url>" + notify_url + "</notify_url>"; formData += "<openid>" + openid + "</openid>"; formData += "<out_trade_no>" + out_trade_no + "</out_trade_no>"; formData += "<total_fee>" + total_fee + "</total_fee>"; formData += "<trade_type>" + trade_type + "</trade_type>"; formData += "<sign>" + sign + "</sign>"; formData += "</xml>"; console.log("formData", formData); //统一支付 wx.request({ url: 'https://api.mch.weixin.qq.com/pay/unifiedorder', method: 'POST', head: 'application/x-www-form-urlencoded', data: formData, //设置请求的 header success: function (res) { console.log("返回商户", res.data); var resultCode = util.getXMLNodeValue('result_code', res.data.toString("utf-8")); if (!resultCode || resultCode == 'FAIL') { var errDes = util.getXMLNodeValue('err_code_des', res.data.toString("utf-8")); var returnMsg = util.getXMLNodeValue('return_msg', res.data.toString("utf-8")); wx.showToast({ title: errDes ? errDes : returnMsg, icon: 'none' }) } else { //发起支付 var prepay_id = util.getXMLNodeValue('prepay_id', res.data.toString("utf-8")); //签名 var timeStamp = util.timeStamp(); var nonceStr = util.randomString(); var stringSignTemp = "appId=" + appid + "&nonceStr=" + nonceStr + "&package=prepay_id=" + prepay_id + "&signType=MD5&timeStamp=" + timeStamp + "&key=" + key; console.log("签名字符串", stringSignTemp); var sign = md5.md5(stringSignTemp).toUpperCase(); console.log("签名", sign); var param = { "timeStamp": timeStamp, "package": 'prepay_id=' + prepay_id, "paySign": sign, "signType": "MD5", "nonceStr": nonceStr } console.log("param小程序支付接口参数", param); that.processPay(param); } }, }) }, /* 小程序支付 */ processPay: function (param) { var thia = this; wx.requestPayment({ timeStamp: param.timeStamp, nonceStr: param.nonceStr, package: param.package, signType: param.signType, paySign: param.paySign, success: function (res) { console.log("wx.requestPayment返回信息",res); wx.showToast({ title: '支付成功', icon: 'success' }) setTimeout(function(){ wx.navigateTo({ url: '../storyDetails/storyDetails?id='+thia.data.id, }) },1500) }, fail: function () { console.log("支付失败"); wx.showToast({ title: '支付失败', icon: 'error' }) setTimeout(function(){ wx.navigateTo({ url: '../storyDetails/storyDetails?id='+thia.data.id, }) },1500) }, complete: function () { console.log("支付完成"); } }) } }) util.js/* 时间戳产生函数 */ function timeStamp() { return parseInt(new Date().getTime() / 1000) + '' } /* 随机数 */ function randomString() { var chars = 'ABCDEFGHJKMNPQRSTWXYZabcdefhijkmnprstwxyz0123456789'; var maxPos = chars.length; var pwd = ''; for (var i = 0; i < 32; i++) { pwd += chars.charAt(Math.floor(Math.random() * maxPos)); } return pwd; } /* 获取XML节点信息 */ function getXMLNodeValue(node_name, xml) { var str = ''; var tmp = xml.split("<" + node_name + ">"); if(!tmp[1]){ return; } var _tmp = tmp[1].split("</" + node_name + ">"); if(_tmp[0].indexOf('![CDATA[') != -1){ str = _tmp[0].split('[')[2].split(']')[0]; }else{ str = _tmp[0]; } return str; } module.exports = { randomString: randomString, timeStamp: timeStamp, getXMLNodeValue: getXMLNodeValue } notify_url.php<?php require 'common.php'; $param = xml_array(file_get_contents('php://input')); // file_put_contents('1.txt',file_get_contents('php://input')); if(!empty($param)){ $appid = $param['appid']; $mch_id = $param['mch_id']; $nonce_str = $param['nonce_str']; $out_trade_no = $param['out_trade_no']; $key = $config['payKey']; $md5Arr = $param; unset($md5Arr['sign']); $md5Param = urldecode(http_build_query(arg_sort($md5Arr))).'&key='.$key; // echo $md5Param; $sign = md5($md5Param); if(strtolower($sign) != strtolower($param['sign'])){ exit(array_xml(['return_code' => 'FAIL','return_msg' => '签名验证失败'])); } $arrToXml = ['appid' => $appid,'mch_id' => $mch_id,'nonce_str' => $nonce_str,'out_trade_no' => $out_trade_no]; $sign2 = urldecode(http_build_query(arg_sort($arrToXml))).'&key='.$key; $arrToXml['sign'] = md5($sign2); $xml = array_xml($arrToXml); $xml = get_curl("https://api.mch.weixin.qq.com/pay/orderquery",$xml); $arr = xml_array($xml); if($arr['return_code'] == 'SUCCESS' && $arr['result_code'] == 'SUCCESS' && $arr['trade_state'] == 'SUCCESS'){ $row = getOne("select id,money,status from order_list where order_number='{$out_trade_no}'"); if($row['status'] == 0 && $row['money'] == round(($arr['total_fee']/100),2)){ update('order_list',['status' => 1,'pay_time' => time()],'id='.$row['id']); } echo array_xml(['return_code' => 'SUCCESS']); }else{ echo array_xml(['return_code' => 'FAIL','return_msg' => '验证失败']); } }else{ echo array_xml(['return_code' => 'FAIL','return_msg' => '请发起xml请求']); } // 以下测试用 /* $xml = file_get_contents('1.txt'); echo get_curl('https://域名/notify_url.php',$xml);*/ common.phpfunction get_curl($url, $post = '', $cookie = '', $referer = '', $proxy = '', $header = 0, $userAgent = '', $httpheader = []) { $curl = curl_init(); // 配置curl中的http协议->可配置的荐可以查PHP手册中的curl_ curl_setopt($curl, CURLOPT_URL, $url); if ($post) { // POST数据 curl_setopt($curl, CURLOPT_POST, 1); // 把post的变量加上 if (is_array($post)) { curl_setopt($curl, CURLOPT_POSTFIELDS, http_build_query($post)); } else { curl_setopt($curl, CURLOPT_POSTFIELDS, $post); } if ($arr = @json_decode($post, true)) { if (is_array($arr)) { $httpheader[] = 'Content-Type: application/json; charset=utf-8'; $httpheader[] = 'Content-Length: ' . strlen($post); } } } if ($referer) { $httpheader[] = 'Referer: ' . $referer; //模拟来路 $httpheader[] = 'Origin: ' . $referer; } else { $httpheader[] = 'Referer: ' . $url; //模拟来路 $httpheader[] = 'Origin: ' . $url; } if ($cookie) { $httpheader[] = 'Cookie: ' . $cookie; //模拟cookie } if ($proxy) { $proxy = explode(':', $proxy); if (!empty($proxy[1])) { curl_setopt($curl, CURLOPT_PROXY, $proxy[0]); //代理服务器地址 curl_setopt($curl, CURLOPT_PROXYPORT, $proxy[1]); //代理服务器端口 } $httpheader[] = 'X-FORWARDED-FOR: ' . $proxy[0]; //模拟ip $httpheader[] = 'CLIENT-IP: ' . $proxy[0]; //模拟ip } else { $httpheader[] = 'X-FORWARDED-FOR: ' . $_SERVER['REMOTE_ADDR']; //模拟ip $httpheader[] = 'CLIENT-IP: ' . $_SERVER['REMOTE_ADDR']; //模拟ip } if ($header) { curl_setopt($curl, CURLOPT_HEADER, TRUE); //获取响应头信息 } if ($userAgent) { $httpheader[] = 'User-Agent: ' . $userAgent; //模拟用户浏览器信息 } else { $httpheader[] = 'User-Agent: ' . (!empty($_SERVER['HTTP_USER_AGENT']) ? $_SERVER['HTTP_USER_AGENT'] : 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Safari/537.36'); } $httpheader[] = 'Host: ' . @parse_url($url)['host']; curl_setopt($curl, CURLOPT_HTTPHEADER, $httpheader); //模拟请求头 curl_setopt($curl, CURLOPT_TIMEOUT, 10); //只需要设置一个秒的数量就可以 curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1); //返回字符串,而非直接输出到屏幕上 curl_setopt($curl, CURLOPT_FOLLOWLOCATION, 1); //跟踪爬取重定向页面 curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false); curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false); curl_setopt($curl, CURLOPT_ENCODING, ''); //解决网页乱码问题 // 执行这个请求 $ret = curl_exec($curl); if ($header) { $headerSize = curl_getinfo($curl, CURLINFO_HEADER_SIZE); $header = substr($ret, 0, $headerSize); $body = substr($ret, $headerSize); $ret = array(); $ret['header'] = $header; $ret['body'] = $body; } curl_close($curl); return $ret; } // xml转数组 function xml_array($xml) { //禁止引用外部xml实体 libxml_disable_entity_loader(true); $xmlstring = simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA); $val = json_decode(json_encode($xmlstring), true); return $val; } // 数组转xml function array_xml($arr) { $xml = "<xml>"; foreach ($arr as $key => $val) { if (is_array($val)) { $xml .= "<" . $key . ">" . array_xml($val) . "</" . $key . ">"; } else { $xml .= "<" . $key . ">" . $val . "</" . $key . ">"; } } $xml .= "</xml>"; return $xml; } // 对数组排序 function arg_sort($para) { ksort($para); reset($para); return $para; } 微信小程序开发用户授权登录、获取手机号、昵称、头像 https://www.zzwws.cn/archives/6330/ 2022-02-28T11:51:00+08:00 login.wxml<button open-type="getUserProfile" bindtap="getUserProfile"> 获取头像昵称 </button> <button bindtap='onLogin'>授权登录</button> <button open-type="getPhoneNumber" bindgetphonenumber="getPhoneNumber">获取手机号</button> server.js// 服务接口地址 const base = 'http://localhost/'; // 开放接口配置 export default{ apiUrl:base + 'api.php' } login.js//加载公共api文件server.js import API from '../../config/server.js' Page({ /** * 页面的初始数据 */ data: { }, /** * 生命周期函数--监听页面加载 */ onLoad: function () { this.userLogin(); var uid = wx.getStorageSync('uid'); console.log(uid); }, userLogin(){ if(!wx.getStorageSync('uid')){ onLogin() }else{ wx.request({ url: API.apiUrl, method: 'post', data: {act: 'isUser',id: wx.getStorageSync('uid')}, success: function(res){ if(res.data.code == -1){ onLogin() }else{ wx.checkSession({ success () { //session_key 未过期,并且在本生命周期一直有效 console.log('已登录'); var pages = getCurrentPages() //获取加载的页面 var currentPage = pages[pages.length-1] //获取当前页面的对象 var url = currentPage.route //当前页面url var options = currentPage.options //如果要获取url中所带的参数可以查看options console.log(url) if(url.indexOf('/login') != -1){ wx.navigateBack({ delta: 2 }) } }, fail () { // session_key 已经失效,需要重新执行登录流程 onLogin() //重新登录 console.log('未登录'); } }) } } }) } }, onLogin() { wx.login({ success (res) { if (res.code) { //发起网络请求 wx.request({ url: API.apiUrl, method: 'post', data: { act: 'onLogin', code: res.code }, success:function(res){ console.log(res.data) if(res.data.code == 0){ wx.setStorage({key: 'uid',data: res.data.id}) }else{ wx.showToast({ title: '获取用户id失败', icon: 'error' }) setTimeout(() => { this.onLogin(); }, 1500); } } }) } else { console.log('登录失败!' + res.errMsg) } } }) }, getUserProfile(e){ wx.getUserProfile({ desc: '用于完善会员资料', // 声明获取用户个人信息后的用途,后续会展示在弹窗中,请谨慎填写 success: (res) => { console.log(res.userInfo) wx.setStorage({key: 'userInfo',data: res.userInfo}) } }) }, getPhoneNumber (e) { console.log(e.detail.code) wx.request({ url: API.apiUrl, method: 'post', data: { act: 'getPhone', code: e.detail.code }, success:function(res){ console.log(res.data) if(res.data.code != 0){ wx.showToast({ title: res.data.msg, icon: 'error' }) }else{ wx.setStorage({key: 'phone',data: res.data.phone}) } } }) } }) api.php<?php header('content-type: application/json;charset=utf-8'); require 'common.php'; $post = $_POST; $data = ['code' => -1,'msg' => '获取失败']; if(empty($post)){ $post = json_decode(file_get_contents('php://input'),true); } switch($post['act']){ case 'onLogin': if(!preg_match('/\w/',$post['code'])){ $data['msg'] = 'code格式错误'; break; } $code2Session = get_curl("https://api.weixin.qq.com/sns/jscode2session?appid={$config['appId']}&secret={$config['appSecret']}&js_code={$post['code']}&grant_type=authorization_code"); $code2Session = json_decode($code2Session,true); if(isset($code2Session['errcode']) && $code2Session['errcode'] != 0){ $data['msg'] = '登录失败'; }else{ $data = ['code' => 0,'msg' => '登录成功']; $row = getOne("select id from userlist where openid='{$code2Session['openid']}'"); if($row){ $data['id'] = $row['id']; }else{ $res = insert('userlist',['nickname' => '','avatar_url' => '','phone' => '','login_time' => time(),'openid' => $code2Session['openid']]); $data['id'] = $res; } } break; case 'getPhone': if(!preg_match('/\w/',$post['code'])){ $data['msg'] = 'code格式错误'; break; } $getAccessToken = get_curl("https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid={$config['appId']}&secret={$config['appSecret']}"); $getAccessToken = json_decode($getAccessToken,true); $getPhoneNumber = get_curl("https://api.weixin.qq.com/wxa/business/getuserphonenumber?access_token={$getAccessToken['access_token']}",json_encode(['code' => $post['code']])); $getPhoneNumber = json_decode($getPhoneNumber,true); if($getPhoneNumber['errcode'] == 0){ $data['phone'] = $getPhoneNumber['phone_info']['purePhoneNumber']; } break; } echo json_encode($data); 微信小程序获取json数据 https://www.zzwws.cn/archives/6327/ 2022-02-08T17:47:00+08:00 注意:需要先在微信公众平台后台里添加request合法域名,还有必须用httpsindex.wxml<view> <text>{{name}}</text> </view> index.jsonLoad:function(options){ //页面加载完成之后,发送请求获取json数据,options为页面跳转所带来的参数 var that = this; wx.request({ url: '接口地址', method: 'get', dataType: 'json', data: {id: 1}, success:function(res){ console.log(res.data); that.setData({ name: res.data.name }) }, fail:function(){ console.log('请求失败'); } }) } 古风姓氏头像在线制作小程序源码 https://www.zzwws.cn/archives/6243/ 2021-12-14T17:22:08+08:00 下载地址:https://zhizun.lanzouy.com/iMOptxlmgtg 薅羊毛拼团商城小程序V2.7.5 https://www.zzwws.cn/archives/6190/ 2021-12-06T19:14:06+08:00 薅羊毛拼团商城V2.7.5小程序功能模块,无授权,包更新,包含薅羊毛拼团分销插件、购买有小群,可以开源,这个是完整包!新版更新了:修复问题 无需更新小程序测试环境:系统环境:CentOS Linux 7.6.1810 (Core)、运行环境:宝塔 Linux v7.0.3(专业版)、网站环境:Nginx 1.15.10 + MySQL 5.6.46 + PHP-7.1 / PHP-5.6、常见插件:ionCube ;fileinfo ; redis ; Swoole ; sg11下载地址:https://zhizun.lanzoux.com/imvSpxbj59c 学法减分助手pro小程序源码全新ui4.23版本 https://www.zzwws.cn/archives/6058/ 2021-11-11T17:23:10+08:00 1、什么是学法减分“学法减分”是多个城市为了贯彻落实公安交通管理局“接受教育减免道路交通安全违法行为记分”改革的服务措施,提升机动车驾驶员交通安全意识所推广的一项重大措施。机动车驾驶员参加公安机关交通管理部门组织的道路交通安全法律、法规和相关知识学习、考试或者交通安全公益活动,达到要求的,可以申请减免现有累计记分中的记分分值,最高减免6分。2、网上学习考试网上学习可以登录交管123进行查看,按照流程操作即可。如果在答题的过程中,有遇到不会的题目,可以搜索小程序“学法减分助手pro”进行辅助学习,拍照上传自动识别并返回对应的参考答案。网上学习需要在3日内累计学习满30分钟,每次的学习时间必须连续满5分钟,完成学习后在7个工作日内申请参加考试,考试合格的,一次减免1分,一个记分周期内最高可减免6分。网上学习考试时间最高为20分钟,每次答题时长是60秒。系统将随即从题库中抽取20道题作为考试题,题型有判断题、单项选择题、多项选择题。答对18题以上即视为合格,答错或超时未答的题目数累计达3题的,系统自动判定为考试不合格并会退出考试,考试未通过的可以在24小时内申请补考,最多可补考2次。当然,如果你担心考不过,你可以尝试今天上线的这款小程序,微信搜索 “学法减分助手PRO”权威题库,拍照搜题,全国通用。下载地址:https://zhizun.lanzoui.com/ishDRwe50hi 学法减分助手PRO小程序最新源码 https://www.zzwws.cn/archives/6043/ 2021-11-08T17:28:00+08:00 交管推出个学法减分,每个驾驶员可以把被扣的6分,以看视频答题的形式学习回来,然后答题这个一共二十道题每道题60秒,有好多人不会,用咱们的小程序就可以模拟练习强化练习,还有拍照识别题目找到正确答案!点击12123 点击学法减分,之后申请学法减分网上学习,审核通过后开始30分钟的学习,学习通过后点击进入考试。答题过程中注意题库选项的顺序和12123APP的选项顺序完全一致,提示答案是什么就选什么 ,无脑选 下载地址:https://zhizun.lanzoui.com/iqriowalyob