赞
踩
https://mp.weixin.qq.com/s/00tbT1ENFLdhIWElreFxtg
浅谈微信小程序渗透
# 踩坑 | Fiddler雷电模拟器4.0无法抓包(超详细)
https://mp.weixin.qq.com/s/AYVRGWbOCWvQh6fyifqcQQ
https://mp.weixin.qq.com/s/KfhgP97alL_d8mmOY4z44w 使用安卓模拟器挂微信找小程序包脱出来解包的操作太繁琐 MAC PC端微信 使用现有工具(https://github.com/TinyNiko/mac_wxapkg_decrypt) 采用github提到的第一种解密方法 首先需要安装frida 更新pip python3 -m pip install --upgrade pip 安装frida pip3 install frida 安装frida-tools pip3 install frida-tools Windows PC端微信 也是已经有师傅写好解密小程序包的工具了(https://github.com/BlackTrace/pc_wxapkg_decrypt) 找到微信小程序包所在根路径
C:\Users\amingMM\Nox_share\ImageShare
低版本
Android 5 32位
4CPU 6G
反编译
微信小程序开发者,对前端思路的学习。
《解密》与《逆向》
在/data/data/com.tencent.mm/MicroMsg/xxxxxxx(不同微信文件夹也不同)/appbrand/pkg/目录下
存放着刚才访问这个小程序的两个数据包,
“我-设置-切换账号”,点击“添加账号”,
会弹出“登录其他账号”和“注册一个新的账号”选项。进入“注册一个新的账号”,
选择“通过当前微信号辅助注册”,就可以开始安全验证了。
两个包分为子包和主包 压缩后通过模拟器的微信发送到物理机进行反编译 wxappUnpacker进行反编译 CMD进入wxappUnpacker的下载目录,安装依赖包 ``` npm install esprima npm install css-tree npm install cssbeautify npm install vm2 npm install uglify-es npm install js-beautify
用户点击右上角转发
MP-WEIXIN
#ifdef
通过 module.exports 将一个对象导出
色号转换
https://www.bchrt.com/tools/color-convert/
https://www.iconfont.cn/
App.vue 中使用
Vue.prototype.$location
// 在 Vue 组件中访问全局变量
console.log(this.$location)
页面加载时被调用
<script> export default { data(){ }, components: { }, /** * 生命周期函数--监听页面加载 */ onLoad() { }, /** * 生命周期函数--监听页面显示 */ onShow() { } , methods:{ } } </script>
getCurrentPages() 方法获取到当前页面栈的所有页面,
而 pages[pages.length - 2] 表示当前页面栈中的倒数第二个页面,也就是其上一个页面的页面对象。
通过这个方法,我们可以在当前页面中调用上一个页面的方法、获取其数据等操作。
uni-app框架调用https接口
开发小程序
提高vue技术
前端技术
课程需要具备vue基础知识
nodejs 后台
uniapp 小程序 vue
新建界面
添加配置
资源文件
底部导航栏
拾色器
import Take from './components/takeout.vue'
export default {
components:{
Take
},
<template> <view> <block v-for="(item,index) in shoperlist" :key="index"> <view class="content-view"> <view class="content_img"> <image :src="item.logo" mode="aspectFill"></image> </view> <view class="content_title"> <text class="content_shoper">{{item.shoper}}</text> <view class="content_result"> <text>月销售{{1}}</text> <text>距您约{{item.duration}}分钟</text> </view> <view class="content_end"> <image src=""></image> <text>{{item.types}}</text> </view> </view> </view> </block> </view> </template>
<script> export default { data() { return { shoperlist: [{ 'logo': 'https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fqny.smzdm.com%2F202205%2F23%2F628b811626a976429.jpg_d250.jpg&refer=http%3A%2F%2Fqny.smzdm.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=auto?sec=1668590466&t=06731bdad94505329d8a942c1e08e66b', 'shoper': '啦啦啦', 'duration': 30, 'types': '大傻逼' } ] } }, } </script>
.content-view text{display: block;} .content-view{display: flex; justify-content: space-between; height: 200upx !important; overflow: hidden; border-bottom: 1rpx solid #E4E8EB; padding-bottom: 5upx; margin: 30upx 0; color: #898989;} .content_img{ width: 350upx !important; height: 200upx !important; } .content_img image{ width: 100%; height: 100%; border-radius: 10upx; } .content_title{ width: 100%; padding-left: 10upx; font-size: 24upx; } .content_shoper{ color: #333333; height: 50upx; font-size: 33upx; font-weight: bold; line-height: 50upx; display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 1; overflow: hidden; } .content_result{ display: flex; justify-content: space-between; height: 50upx; line-height: 50upx; } .content_end{ display: flex; align-items: center; height: 50upx; line-height: 50upx; } .content_end text {width: 130upx;} .content_end image {width: 24upx; height: 24upx; padding-right: 10upx;}
<style scoped>
@import '../../../common/css/take.css'
</style>
在父组件中通过给子组件的 prop 属性绑定一个值,来传递参数。
<template> <child-component :msg="message"></child-component> </template> <template> <div>{{ msg }}</div> </template> <script> export default { props: { msg: { type: String, default: '' } } } </script>
通过父组件在自身的插槽中填充内容,子组件通过插槽将父组件的内容显示出来。
<template>
<child-component>
<p>{{ message }}</p>
</child-component>
</template>
<template>
<div>
<slot></slot>
</div>
</template>
同时并发请求 多个接口,同时得到 多个接口数据
object 对象
可以 正常 调试 、、、
(需要软件开发 联系我哦)
一、为什么会出现跨域问题
出于浏览器的同源策略限制。同源策略(Sameoriginpolicy)是一种约定,
它是浏览器最核心也最基本的安全功能,如果缺少了同源策略,则浏览器的正常功能可能都会受到影响。
可以说Web是构建在同源策略基础之上的,浏览器只是针对同源策略的一种实现。
同源策略会阻止一个域的javascript脚本和另外一个域的内容进行交互。
所谓同源(即指在同一个域)就是两个页面具有相同的协议(protocol),主机(host)和端口号(port)
什么是跨域
当一个 浏览器 请求url的协议、域名、端口三者之间任意一个与当前页面url不同即为跨域
当前页面url 被请求页面url 是否跨域 原因
http://www.test.com/ http://www.test.com/index.html 否 同源(协议、域名、端口号相同)
http://www.test.com/ https://www.test.com/index.html 跨域 协议不同(http/https)
http://www.test.com/ http://www.baidu.com/ 跨域 主域名不同(test/baidu)
http://www.test.com/ http://blog.test.com/ 跨域 子域名不同(www/blog)
http://www.test.com:8080/ http://www.test.com:7001/ 跨域 端口号不同(8080/7001)
官方定义: OPTIONS方法是用于请求获得由Request-URI标识的资源在请求/响应的通信过程中可以使用的功能选项。 通过这个方法,客户端可以在采取具体资源请求之前,决定对该资源采取何种必要措施,或者了解服务器的性能。 出于安全考虑,并不是所有域名都可以访问后端服务。 在正式跨域之前,浏览器会根据需要发起一次预检(也就是 OPTIONS 请求), 用来让服务端返回允许的方法(如get、post), 允许被跨域访问的Origin(来源或者域),还有是否需要Credentials(认证信息)等。 浏览器将 CORS 分为两类 简单请求 不会进行预检,对于简单请求,浏览器直接请求,会在请求头信息中,增加一个origin字段, 来说明本次请求来自哪个源(协议+域名+端口) 同时满足下列三大条件,就属于简单请求,否则属于非简单请求 1.请求方式只能是:GET、POST、HEAD 2.HTTP请求头限制这几种字段: Accept、Accept-Language、Content-Language、Content-Type、Last-Event-ID 3.Content-type取:application/x-www-form-urlencoded、multipart/form-data、text/plain
第一种:在项目根目录下(即跟App.vue同级)建vue.config.js,这个文件会默认优先加载
这个 是 测试 时候 用的 仅供参考
格式
module.exports = {
devServer:{
port:'8080',
disableHostCheck:true,
proxy:{
'/dpc':{
target:'http://XXXXX:9088',
changeOrigin:true,
pathRewrite:{
'^/dpc': ''
}
}
}
}
}
第二种:在manifest.json的代码视图中 根节点中(即{}中),做如下声明
"h5": { "devServer": { "port": 8080, //浏览器运行端口 "disableHostCheck": true, "proxy": { "/dpc": { "target": "XXXXXX:9088", //实际请求服务器地址 "changeOrigin": true, "secure": true, "pathRewrite": { "^/dpc": "" } } } } }
var BASE_URL = 'http:XXXXXX:9088'; //不是h5默认这个地址 // #ifdef H5 BASE_URL = '/dpc'; //H5下将地址修改为/dpc // #endif //附上网络请求的封装 export default (options)=>{ uni.showLoading({ title:'加载中...' }) return new Promise((resolve,reject) =>{ uni.request({ url:BASE_URL + options.url, method:options.method || 'GET', data:options.data || {}, success(res) { if(res){ resolve(res.data) } }, fail(err) { reject(err) }, complete() { uni.hideLoading() } }) }) }
可以直接搬
"h5" : {
"router" : {
"mode" : "history",
"base" : "/h5/h5/" // 配置引用的正确的文件路径
},
"domain" : "https://testapi.kemiandan.com/h5/h5"
}
然后把打包后的文件放在可访问/h5/h5目录下
访问路径 https://testapi.kemiandan.com/h5/h5/即可访问
安卓端 跟 浏览器端 差不多 就是 发个 OPTIONS 请求 跨域 验证 到 后端
devServe是开发时候用的,正式环境不走这里
如果 你 还用 devserve
你会发现 请求 就跑nginx 前端服务器 去了 你的 proxy 没起作用
所以 发布时候 就得 在 nginx 服务器 和 后端接口方面 入手
android 的 webview 发送 校验options 到 后端
POST 请求 失败
options在此问题中属于第二种,当涉及到跨域时,并且是post请求时,
本地服务器会先发送一个options请求到服务器,如果服务器认为options请求时无危险性且认可的,
那么在允许本地服务器发送post请求;
但是如果后端认为options请求是危险且不成功的那么会直接阻止本地服务器发送其他请求
请求三个值
页面
识别id
token
Eg:示例返回结果
{ "code": 1, "msg": "success", "data": { "items": { "s10001": { "id": "s10001", "type": "search", "params": { "placeholder": "搜索商品" }, "style": { "textAlign": "center", "searchStyle": "radius" } }, "n606196612728596": { "id": "n606196612728596", "type": "banner", "style": { "btnColor": "#ffffff", "btnShape": "round" }, "data": { "n400199453786769": { "imgUrl": "http://127.0.0.1/www.cnthink.net/shop/web/uploads/20201216101521e41cf3986.jpg", "imgName": "http://127.0.0.1/www.cnthink.net/shop/web/uploads/20201216101521e41cf3986.jpg", "linkUrl": "page/index/index" }, "n837367626101537": { "imgUrl": "http://127.0.0.1/www.cnthink.net/shop/web/uploads/202012161015204bd302747.jpg", "imgName": "http://127.0.0.1/www.cnthink.net/shop/web/uploads/202012161015204bd302747.jpg", "linkUrl": "page/index/index" }, "n39296042711415": { "dataId": "n39296042711415", "imgUrl": "http://127.0.0.1/www.cnthink.net/shop/web/uploads/20201216101521eec407132.jpg", "imgName": "http://127.0.0.1/www.cnthink.net/shop/web/uploads/20201216101521eec407132.jpg", "linkUrl": "page/index/index" }, "n253302235811058": { "dataId": "n253302235811058", "imgUrl": "http://127.0.0.1/www.cnthink.net/shop/web/uploads/202012161015214ae427082.jpg", "imgName": "http://127.0.0.1/www.cnthink.net/shop/web/uploads/202012161015214ae427082.jpg", "linkUrl": "page/index/index" }, "n894849566788663": { "dataId": "n894849566788663", "imgUrl": "http://127.0.0.1/www.cnthink.net/shop/web/uploads/20201216101521f14513173.jpg", "imgName": "http://127.0.0.1/www.cnthink.net/shop/web/uploads/20201216101521f14513173.jpg", "linkUrl": "page/index/index" } } } }, "newest": [ { "goods_id": 3, "goods_name": "外星人", "category_id": 10003, "spec_type": 10, "deduct_stock_type": 20, "content": "<p>1111</p>", "goods_sort": 100, "delivery_id": 10003, "goods_status": { "text": "上架", "value": 10 }, "spec": [ { "goods_spec_id": 5, "goods_id": 3, "goods_no": "20201226", "goods_price": "111.00", "line_price": "1111.00", "stock_num": 11, "goods_sales": 0, "goods_weight": 111, "spec_sku_id": "" } ], "category": { "category_id": 10003, "name": "电脑", "parent_id": 0, "image_id": 10014, "sort": 1, "create_time": "2020-12-26 13:47:14" }, "image": [ { "id": 12, "goods_id": 3, "image_id": 10016, "file_path": "http://192.168.0.100/www.cnthink.net/shop/web/uploads/2020122613485531f529442.png", "file_name": "2020122613485531f529442.png", "file_url": "" } ], "goods_sales": 0 }, { "goods_id": 2, "goods_name": "外星人", "category_id": 10003, "spec_type": 10, "deduct_stock_type": 20, "content": "<p><img src=\"http://127.0.0.1/www.cnthink.net/shop/web/uploads/20201226134850d97b07122.png\" _src=\"http://127.0.0.1/www.cnthink.net/shop/web/uploads/20201226134850d97b07122.png\" style=\"\"/></p><p><img src=\"http://127.0.0.1/www.cnthink.net/shop/web/uploads/2020122613485531f529442.png\" _src=\"http://127.0.0.1/www.cnthink.net/shop/web/uploads/2020122613485531f529442.png\" style=\"\"/></p><p><br/></p>", "goods_sort": 1, "delivery_id": 10003, "goods_status": { "text": "上架", "value": 10 }, "spec": [ { "goods_spec_id": 4, "goods_id": 2, "goods_no": "20201226", "goods_price": "50000.00", "line_price": "40000.00", "stock_num": 10000, "goods_sales": 0, "goods_weight": 36, "spec_sku_id": "" } ], "category": { "category_id": 10003, "name": "电脑", "parent_id": 0, "image_id": 10014, "sort": 1, "create_time": "2020-12-26 13:47:14" }, "image": [ { "id": 11, "goods_id": 2, "image_id": 10013, "file_path": "http://192.168.0.100/www.cnthink.net/shop/web/uploads/20201226134619131288787.png", "file_name": "20201226134619131288787.png", "file_url": "" } ], "goods_sales": 0 } ], "best": [ { "goods_id": 2, "goods_name": "外星人", "category_id": 10003, "spec_type": 10, "deduct_stock_type": 20, "content": "<p><img src=\"http://127.0.0.1/www.cnthink.net/shop/web/uploads/20201226134850d97b07122.png\" _src=\"http://127.0.0.1/www.cnthink.net/shop/web/uploads/20201226134850d97b07122.png\" style=\"\"/></p><p><img src=\"http://127.0.0.1/www.cnthink.net/shop/web/uploads/2020122613485531f529442.png\" _src=\"http://127.0.0.1/www.cnthink.net/shop/web/uploads/2020122613485531f529442.png\" style=\"\"/></p><p><br/></p>", "goods_sort": 1, "delivery_id": 10003, "goods_status": { "text": "上架", "value": 10 }, "spec": [ { "goods_spec_id": 4, "goods_id": 2, "goods_no": "20201226", "goods_price": "50000.00", "line_price": "40000.00", "stock_num": 10000, "goods_sales": 0, "goods_weight": 36, "spec_sku_id": "" } ], "category": { "category_id": 10003, "name": "电脑", "parent_id": 0, "image_id": 10014, "sort": 1, "create_time": "2020-12-26 13:47:14" }, "image": [ { "id": 11, "goods_id": 2, "image_id": 10013, "file_path": "http://192.168.0.100/www.cnthink.net/shop/web/uploads/20201226134619131288787.png", "file_name": "20201226134619131288787.png", "file_url": "" } ], "goods_sales": 0 }, { "goods_id": 3, "goods_name": "外星人", "category_id": 10003, "spec_type": 10, "deduct_stock_type": 20, "content": "<p>1111</p>", "goods_sort": 100, "delivery_id": 10003, "goods_status": { "text": "上架", "value": 10 }, "spec": [ { "goods_spec_id": 5, "goods_id": 3, "goods_no": "20201226", "goods_price": "111.00", "line_price": "1111.00", "stock_num": 11, "goods_sales": 0, "goods_weight": 111, "spec_sku_id": "" } ], "category": { "category_id": 10003, "name": "电脑", "parent_id": 0, "image_id": 10014, "sort": 1, "create_time": "2020-12-26 13:47:14" }, "image": [ { "id": 12, "goods_id": 3, "image_id": 10016, "file_path": "http://192.168.0.100/www.cnthink.net/shop/web/uploads/2020122613485531f529442.png", "file_name": "2020122613485531f529442.png", "file_url": "" } ], "goods_sales": 0 } ] } }
<block v-if="item.type === 'banner'">
限制手段及绕过方法:
1、未做限制
使用其他浏览器可直接打开页面进行浏览
2、通过 UserAgent 来限制
现象:使用其他浏览器打开后会跳转到其他页面 或者 有弹窗提示,但是不会跳到open.weixin.qq.com域名去。
处理方法:直接模拟UA访问,chrome内置了这个功能。
如下为微信UA(一般情况下这两个作用一样,实际上哪怕UA里只填一个MicroMessenger都是可以绕过去的):
安卓微信UA:
Mozilla/5.0 (Linux; U; Android 4.1.2; zh-cn; Chitanda/Akari) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30 MicroMessenger/6.0.0.58_r884092.501 NetType/WIFI
03emulate-UA.jpg
ios微信UA:
Mozilla/5.0 (iPhone; CPU iPhone OS 8_0 like Mac OS X) AppleWebKit/600.1.4 (KHTML, like Gecko) Mobile/12A365 MicroMessenger/5.4.1 NetType/WIFI
3、利用了微信oauth做限制
有些对用户身份验证要求比较高的页面,则会利用微信的OAUTH来拉取openid做验证,这种就不仅仅是改UA这么容易绕过去了。好在也不是无解,因为身份验证信息一般都是存在Cookies里的,所以我们可以直接模拟Cookies来让服务器误以为我们是在微信内做的请求。
现象:使用其他浏览器打开后会跳转到open.weixin.qq.com域名,且页面提示请在微信客户端打开链接。
处理方法:
a、将浏览器UA改为微信的,然后刷新页面,会发现不再提示请在微信客户端打开链接了,但是整个页面一片空白。
b、使用抓包工具获取Cookie
c、添加获取到的Cookie信息,可使用 EditThisCookies 添加或修改Cookies。Firefox的话使用Firebug自带的编辑功能即可。
d、重新输入链接访问,成功。
其他方法1:利用微信官方的tbs调试。
其他方法2:利用QQ浏览器内置的微信调试工具。
注:绕过限制进去页面后有部分功能无法正常使用,是由于页面使用了微信的jssdk内置方法(wx.xx之类的)。
请在微信客户端打开链接 渗透测试
小程序 框架
组件 表单元素—> 布局 flex 排版(官方建议 可响应式)
div js css 布局排版
·
{
"navigationBarBackgroundColor": "#5677FC",
"navigationBarTextStyle": "white",
"navigationBarTitleText": "Thor UI"
}
<view class="page_hd">
<view class="page_title" bindtap="doc">
<image src="../../static/images/index/logo.png" class="logo"></image>
<view class="title">Thor UI
<view class="tui-badge">文档</view>
</view>
</view>
<view class="page_desc">小程序
<text class="link" bindtap="template">代码片段</text>分享,源码可去
<text class="link" bindtap="github">GitHub</text>下载</view>
</view>
data: { current: 0, tabbar: [{ icon: "home", text: "首页", size: 21 }, { icon: "category", text: "分类", size: 24 }, { icon: "cart", text: "购物车", size: 22 }, { icon: "people", text: "我的", size: 24 }], hotSearch: [ "休闲零食", "自热火锅", "小冰箱迷你" ], banner: [ "1.jpg", "2.jpg", "3.jpg", "4.jpg", "5.jpg" ], category: [{ img: "1.jpg", name: "短袖T恤" }, { img: "2.jpg", name: "足球" }, { img: "3.jpg", name: "运动鞋" }, { img: "4.png", name: "中老年" }, { img: "5.png", name: "甜美风" }, { img: "6.jpg", name: "鱼尾裙" }, { img: "7.jpg", name: "相机配件" }, { img: "8.jpg", name: "护肤套装" }, { img: "9.jpg", name: "单肩包" }, { img: "10.jpg", name: "卫衣" }], newProduct: [{ name: "时尚舒适公主裙高街修身长裙", present: 198, original: 298, pic: "1.jpg", type: 1, isLabel: true }, { name: "高街修身雪纺衫", present: 398, original: 598, pic: "2.jpg", type: 2, isLabel: true }, { name: "轻奢商务上衣", present: 99, original: 199, pic: "3.jpg", type: 1, isLabel: true }, { name: "品质牛皮婚鞋牛皮婚鞋品质就是好", present: 99, original: 199, pic: "5.jpg", type: 1, isLabel: true }, { name: "轻奢时尚大包限时新品推荐", present: 99, original: 199, pic: "6.jpg", type: 1, isLabel: false }, { name: "高街修身长裙", present: 999, original: 1299, pic: "4.jpg", type: 2, isLabel: true }], productList: [{ img: 1, name: "欧莱雅(LOREAL)奇焕光彩粉嫩透亮修颜霜 30ml(欧莱雅彩妆 BB霜 粉BB 遮瑕疵 隔离)", sale: 599, factory: 899, payNum: 2342 }, { img: 2, name: "德国DMK进口牛奶 欧德堡(Oldenburger)超高温处理全脂纯牛奶1L*12盒", sale: 29, factory: 69, payNum: 999 }, { img: 3, name: "【第2支1元】柔色尽情丝柔口红唇膏女士不易掉色保湿滋润防水 珊瑚红", sale: 299, factory: 699, payNum: 666 }, { img: 4, name: "百雀羚套装女补水保湿护肤品", sale: 1599, factory: 2899, payNum: 236 }, { img: 5, name: "百草味 肉干肉脯 休闲零食 靖江精制猪肉脯200g/袋", sale: 599, factory: 899, payNum: 2399 }, { img: 6, name: "短袖睡衣女夏季薄款休闲家居服短裤套装女可爱韩版清新学生两件套 短袖粉色长颈鹿 M码75-95斤", sale: 599, factory: 899, payNum: 2399 }, { img: 1, name: "欧莱雅(LOREAL)奇焕光彩粉嫩透亮修颜霜", sale: 599, factory: 899, payNum: 2342 }, { img: 2, name: "德国DMK进口牛奶", sale: 29, factory: 69, payNum: 999 }, { img: 3, name: "【第2支1元】柔色尽情丝柔口红唇膏女士不易掉色保湿滋润防水 珊瑚红", sale: 299, factory: 699, payNum: 666 }, { img: 4, name: "百雀羚套装女补水保湿护肤品", sale: 1599, factory: 2899, payNum: 236 } ], pageIndex: 1, loadding: false, pullUpOn: true },
<block wx:for="{{tabbar}}" wx:key="{{index}}">
<view class="tui-tabbar-item {{current==index?'tui-item-active':''}}" data-index="{{index}}" bindtap="tabbarSwitch">
<tui-icon name="{{current==index?item.icon+'-fill':item.icon}}" color="{{current==index?'#E41F19':'#666'}}" size="{{item.size}}" class="{{index==0?'tui-ptop-4':''}}"></tui-icon>
<view class="tui-scale">{{item.text}}</view>
</view>
</block>
tabbarSwitch: function(e) { let index = e.currentTarget.dataset.index; this.setData({ current: index }) if (index != 0) { if (index == 1) { this.classify(); } else if (index == 2) { wx.navigateTo({ url: '../mall-extend/shopcart/shopcart' }) } else { wx.navigateTo({ url: '../mall-extend/my/my' }) } } },
uni.setTabBarBadge({ //显示数字
index: 4, //tabbar下标
text: '6' //数字
})
<view class="nav-tabs">
<view class="tab-list {{currentTab == idx?'active':'default'}}"
wx:for="{{tabArray}}"
wx:for-index="idx"
wx:for-item="itemName"
data-current="{{idx}}"
bindtap="swichNav">{{itemName}}
</view>
</view>
<view class="{{currentTab == idx?'show':'hidden'}} tab-content" wx:for="{{tabArray}}" wx:for-index="idx" wx:for-item="itemName">{{itemName}}</view>
<!--可滑动切换tanbar-->
<view class="nav-tabs">
<view class="tab-list {{currentTab == idx?'active':'default'}}" wx:for="{{tabArray}}" wx:for-index="idx" wx:for-item="itemName" data-current="{{idx}}" bindtap="swichNav">{{itemName}}</view>
</view>
<swiper current="{{currentTab}}" class="tab-content" duration="300" bindchange="bindChange">
<swiper-item wx:for="{{tabArray}}" wx:for-index="idx" wx:for-item="itemName" class="">
<view class="">{{itemName}}</view>
</swiper-item>
</swiper>
/**index.wxss**/ page{ display: flex; flex-direction: column; height: 100%; } .nav-tabs{ width: 100%; height: 75rpx; display: flex; } .tab-content{ flex: 1; } .default{ line-height:75rpx; text-align:center; flex:1; border-bottom:1px solid #eee; color:#000; font-weight:bold; font-size:28rpx; } .active{ line-height:75rpx; text-align:center; color:#fc5558; flex:1; border-bottom:1px solid red; font-weight:bold; font-size:28rpx; } .show{ display:block; flex: 1; } .hidden{ display:none; flex: 1; }
data: {
currentTab:0,
tabArray:["tab1", "tab2", "tab3", "tab4"]
},
bindChange: function( e ) {
var that = this;
that.setData( { currentTab: e.detail.current });
},
swichNav: function( e ) {
var that = this;
console.log(e.target)
if( this.data.currentTab === e.target.dataset.current ) {
return false;
} else {
that.setData( {
currentTab: e.target.dataset.current
})
}
},
<view class="tui-bg-box">
<image src=" /bg_login.png" class="tui-bg-img"></image>
<image src=" /mine_def_touxiang_3x.png" class="tui-photo"></image>
<view class="tui-login-name">Thor UI</view>
</view>
.tui-bg-box {
width: 100%;
box-sizing: border-box;
position: relative;
padding-top: 44rpx;
}
.tui-bg-img {
width: 100%;
height: 346rpx;
display: block;
position: absolute;
top: 0;
z-index: -1;
}
.tui-photo {
height: 138rpx;
width: 138rpx;
display: block;
margin: 10rpx auto 0 auto;
border-radius: 50%;
}
.tui-login-name {
width: 128rpx;
height: 40rpx;
font-size: 30rpx;
color: #fff;
margin: 36rpx auto 0 auto;
text-align: center;
}
.tui-login-from {
width: 100%;
padding: 128rpx 104rpx 0 104rpx;
box-sizing: border-box;
}
.tui-line-cell {
padding: 27rpx 0;
display: -webkit-flex;
display: flex;
-webkiit-align-items: center;
align-items: center;
position: relative;
}
/** * * 配套视频教程请移步微信->小程序->灵动云课堂 * 关注订阅号【huangxiujie85】,第一时间收到教程推送 * * @link http://blog.it577.net * @author 黄秀杰 */ const AV = require('../../utils/av-weapp.js') Page({ data: { banner: [], goods: [], bannerHeight: Math.ceil(290.0 / 750.0 * getApp().screenWidth) }, onLoad: function (options) { this.loadBanner(); this.loadMainGoods(); this.getInviteCode(options); /* debug navi */ // wx.navigateTo({ // url: "/pages/goods/detail/detail?objectId=5816e3b22e958a0054a1d711" // }); }, getInviteCode: function (options) { if (options.uid != undefined) { wx.showToast({ title: '来自用户:' + options.uid + '的分享', icon: 'success', duration: 2000 }) } }, loadBanner: function () { var that = this; var query = new AV.Query('Banner'); // query.include('image'); query.find().then(function (bannerObjects) { var banner = []; for (var i = 0; i < bannerObjects.length; i++) { banner.push(bannerObjects[i].get('image').get('url')); } that.setData({ banner: banner }); }); }, loadMainGoods: function () { var that = this; var query = new AV.Query('Goods'); query.equalTo('isHot', true); query.find().then(function (goodsObjects) { that.setData({ goods: goodsObjects }); }); }, showDetail: function (e) { var index = e.currentTarget.dataset.index; var goodsId = this.data.goods[index].id; wx.navigateTo({ url: "../goods/detail/detail?objectId=" + goodsId }); }, showCategories: function () { // wx.navigateTo({ // url: "../category/category" // }); wx.switchTab({ url: "../category/category" }); }, showOrders: function () { wx.navigateTo({ url: "../order/list/list?status=1" }); }, onShareAppMessage: function () { return { title: '灵动开源电商系统', desc: '一个基于LeanCloud开发的开源电商系统', path: '/pages/index/index?uid=4719784' } }, showGoods: function () { wx.navigateTo({ url: '../goods/detail/detail?objectId=5816e3b22e958a0054a1d711' }); } })
onlaunch:
当小程序初始化完成时,会触发 onLaunch
(全局只触发一次)(app.js)
onLoad: 页面加载
小程序注册完成后,加载页面,触发onLoad方法。
一个页面只会调用一次,可以在 onLoad 中获取打开当前页面所调用的 query 参数(页面js)。
onShow: 页面显示
页面载入后触发onShow方法,显示页面。
每次打开页面都会调用一次(比如当小程序有后台进入到前台运行或重新进入页面时)。
onReady:
首次显示页面,页面初次渲染完成,会触发onReady方法,渲染页面元素和样式,一个页面只会调用一次,代表页面已经准备妥当,可以和视图层进行交互。
对界面的设置如wx.setNavigationBarTitle请在onReady之后设置。
onHide: 页面隐藏
当navigateTo或底部tab切换时调用。
onUnload: 页面卸载
当使用重定向方法wx.redirectTo(OBJECT)或关闭当前页返回上一页wx.navigateBack的时候调用。
基本上可以说执行顺序为onLaunch–onLoad–onShow–onReady–onHide.
虽然说onLaunch在onLoad之前执行,
但是在onLaunch里请求获取是否有权限,等待返回值的时候Page里的onLoad事件就已经执行了。
解决办法:
在APP里面onLanch中的网络请求中设置判断
if (this.userInfoReadyCallback) {
this.userInfoReadyCallback(res)
}
在page的onLoad中设置一个回调
app.userInfoReadyCallback = res => {
if (res != ‘’) {
console.log(“app.globalData.userInfo”)
}
}
typeof cb == “function” && cb( this.globalData.userInfo )
— app.js 结束
- 引入了 一个 模版文件
- Navigation 页面链接
<view class='XXXX' wx:for="{{taskLists}}" data-id='{{item.objectId}}' bindtap='XXXX'>
在js的XXXX里,利用e.currentTarget.dataset.*接收data-的值
XXXX:function(e){
var taskId = e.currentTarget.dataset.id;
wx.navigateTo({
url: 'xxxx/taskDetail?taskId=' + taskId,
})
},
url拼接字符串的方式为: url: 'xxxx/taskDetail?taskId=' + taskId
然后我们去到跳转的页面,通过onload函数就可以打印出传过来的参数啦:
onLoad: function (options) {
console.log(options)
},
多个组件标签 使用一个 标签将多个组件包装起来,并在上边使用 wx:if 控制属性
类似 block wx:if,也可以将 wx:for 用在标签上,以渲染一个包含多节点的结构块
swiper-item 仅可放置在swiper组件中,宽高自动设置为100%。
item-id string 否 该 swiper-item 的标识符
、
保留当前页面,跳转到应用内的某个页面。
但是不能跳到 tabbar 页面。
使用 wx.navigateBack 可以返回到原页面。小程序中页面栈最多十层。
@keyframes 规则
const 限定一个变量不允许被改变,产生静态作用
require是运行时调用,所以require理论上可以运用在代码的任何地方
JavaScript SDK 安装指南 :
我们不用安装,只是为了直观的了解 LeanCloud 的一些界面、设置,比如,CDN加速 设置、LeanCloud的github。
数据存储入门教程 · JavaScript :
这里有个可操作的demo,由于Hexo主题中已经有关于LeanCloud的代码,我没有执行这个demo,
直接拿Hexo主题中的LeanCloud代码来测试。
其实为了更好的理解LeanCloud的知识,还是需要动手操作一下demo的。
数据存储开发指南 · JavaScript :
这篇是必读,如果是利用LeanCloud从头开发一些功能,就需要精读这篇帮助。
我只获取了一些基本信息,比如,WEB安全的设置、LeanCloud中的对象AV.Object和AV.File。
对象的创建、保存、读取,对象的属性获取,计数器相关的。
线程的同步和异步是针对多核CPU而言的,没有多核CPU就没有异步的概念(此时全是同步的)
下面以四核CPU为例子,用图解的方式看同步和异步的区别:
异步 success fail complete
![在这里插入图片描述](https://img-blog.csdnimg.cn/20191208151743125.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzMzNjA4MDAw,size_16,color_FFFFFF,t_7
可以 一次设 多个 key
同步异步 两套 【影响执行效率 系统性能】
同步 得等序列代码都跑完
异步 不用等待
<dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-lang3</artifactId> <version>3.5</version> </dependency> <dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>1.2.4</version> </dependency> <!-- 添加httpclient支持 --> <dependency> <groupId>org.apache.httpcomponents</groupId> <artifactId>httpclient</artifactId> <version>4.5.2</version> </dependency> <dependency> <groupId>redis.clients</groupId> <artifactId>jedis</artifactId> <version>2.8.1</version> <type>jar</type> </dependency>
SpringBoot默认会将resources下的application名字开头的properties作为配置文件。
所以只需要添加application.properties就可以了
由于是使用thymeleaf作为模板引擎。可以添加相应的配置:
#thymelea模板配置
spring.thymeleaf.prefix=classpath:/templates/
spring.thymeleaf.suffix=.html
spring.thymeleaf.mode=HTML5
spring.thymeleaf.encoding=UTF-8
spring.thymeleaf.content-type=text/html
spring.thymeleaf.cache=false
spring.resources.chain.strategy.content.enabled=true
spring.resources.chain.strategy.content.paths=/**
为了让系统更具有通用性
分别创建application-dev.properties、application-prod.properties对不同的环境进行配置。
## 微信开放平台
# APPID
wechat.open.appid =
# APPSECRET
wechat.open.appsecret =
# 回调地址
wechat.open.redirect_uri =
在application.properties中
使用spring.profiles.active进行配置环境的选择。
spring.profiles.active = prod
@Getter @Setter @ToString
public class WeChatUserInfo {
String openid;
String nickname;
Integer sex;
String province;
String city;
String country;
String headimgurl;
String privilege;
String unionid;
根据文档进行编写代码。
<view class="page-container">
<view class="head">
<custom-nav fixed="{{false}}" background="#A28A7D">
<view><input type="text" /></view>
</custom-nav>
</view>
<view class="section">
<view wx:for="{{50}}" wx:key="index">text{{index}}</view>
</view>
</view>
.page-container { height: 100vh; display: flex; flex-direction: column; } .head input { width: 100%; height: 100%; background: #fff; border-radius: 64rpx; } .section { flex: 1; overflow: auto; -webkit-overflow-scrolling: touch; }
import { getMenuButtonBoundingClientRectLocal, isSupportNavigation } from '../../utils/storage' Page({ /** * 页面的初始数据 */ data: { }, /** * 生命周期函数--监听页面加载 */ onLoad: function (options) { const { bottom, paddingBottom } = getMenuButtonBoundingClientRectLocal() this.setData({ isSupportNavigation: isSupportNavigation(), navHeight: bottom + paddingBottom, }) },
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。