
动态加载 welcome 欢迎主页
index 页面
<!doctype html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
<meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" />
<link href="css/mui.min.css" rel="stylesheet" />
</head>
<body>
<script src="js/mui.min.js"></script>
<script type="text/javascript" charset="utf-8">
mui.init();
mui.plusReady(function() {
//引导页面-0
var guide = plus.storage.getItem("guide");
if(guide) {
return;
} else {
mui.openWindow({
url: "guide.html",
id: "guide",
show: {
autoShow: true, //页面loaded事件发生后自动显示,默认为true
aniShow: 'fade-in', //页面显示动画,默认为”slide-in-right“;
duration: 800 //页面动画持续时间,Android平台默认100毫秒,iOS平台默认200毫秒;
}
});
}
});
</script>
</body>
</html>
guide 页面
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<meta name="viewport" content="width=device-width, initial-scale=1,maximum-scale=1,user-scalable=no">
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="black">
<link rel="stylesheet" href="css/mui.min.css">
</head>
<body>
<div id="slider" class="mui-slider mui-fullscreen">
<div class="mui-slider-group">
<!-- 第一张 -->
<div class="mui-slider-item" style="background-image: url(img/guide/banner.jpg);">
</div>
<!-- 第二张 -->
<div class="mui-slider-item" style="background-image: url(img/guide/banner01.jpg);">
</div>
<!-- 第三张 -->
<div class="mui-slider-item" style="background-image: url(img/guide/banner02.jpg);">
</div>
<!-- 第四张 -->
<div class="mui-slider-item" style="background-image: url(img/guide/banner03.jpg);">
<button id='enter' class="mui-btn mui-btn-outlined">立即体验</button>
</div>
</div>
</div>
<script src="js/mui.min.js"></script>
<script>
mui.init();
mui.init();
getPicture();
function getPicture() {
var template='';
var btn='';
var slider = mui("#slider");
var gallery=document.getElementById("slider-group")
mui.ajax('http://127.0.0.1/app/home/index.php?r=advertiese/get-home-ad',{
dataType:'json',//服务器返回json格式数据
type:'get',//HTTP请求类型
timeout:10000,//超时时间设置为10秒;
success:function(data){
console.log(JSON.stringify(data));
var ret=data.response;
var result=data.result;
var website='http://10.2.5.76/app/home/';
if (ret==200) {
mui.each(result,function(index,item){
var para=document.createElement("div");
template='<div class="mui-slider-item" style="background-image: url('+website+item.content+');">'
+'</div>';
gallery.innerHTML+=template;
});
btn='<button id="enter" class="mui-btn mui-btn-outlined">'
+"立即体验"
+'</button>';
gallery.innerHTML+=btn;
slider.slider({
interval: 5000
});
enter();
}else{
slider.slider({
interval: 0
});
}
},
error:function(xhr,type,errorThrown){
}
});
}
function enter () {
(function($,doc) {
var enterButton = doc.querySelector('#enter');
enterButton.addEventListener('tap', function(event) {
plus.webview.currentWebview().close();
plus.storage.setItem("guide", plus.runtime.version);
}, false);
$.plusReady(function() {
plus.navigator.closeSplashscreen();
});
}(mui, document));
}
</script>
</body>
</html>
index 页面
<!doctype html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
<meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" />
<link href="css/mui.min.css" rel="stylesheet" />
</head>
<body>
<script src="js/mui.min.js"></script>
<script type="text/javascript" charset="utf-8">
mui.init();
mui.plusReady(function() {
//引导页面-0
var guide = plus.storage.getItem("guide");
if(guide) {
return;
} else {
mui.openWindow({
url: "guide.html",
id: "guide",
show: {
autoShow: true, //页面loaded事件发生后自动显示,默认为true
aniShow: 'fade-in', //页面显示动画,默认为”slide-in-right“;
duration: 800 //页面动画持续时间,Android平台默认100毫秒,iOS平台默认200毫秒;
}
});
}
});
</script>
</body>
</html>
guide 页面
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<meta name="viewport" content="width=device-width, initial-scale=1,maximum-scale=1,user-scalable=no">
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="black">
<link rel="stylesheet" href="css/mui.min.css">
</head>
<body>
<div id="slider" class="mui-slider mui-fullscreen">
<div class="mui-slider-group">
<!-- 第一张 -->
<div class="mui-slider-item" style="background-image: url(img/guide/banner.jpg);">
</div>
<!-- 第二张 -->
<div class="mui-slider-item" style="background-image: url(img/guide/banner01.jpg);">
</div>
<!-- 第三张 -->
<div class="mui-slider-item" style="background-image: url(img/guide/banner02.jpg);">
</div>
<!-- 第四张 -->
<div class="mui-slider-item" style="background-image: url(img/guide/banner03.jpg);">
<button id='enter' class="mui-btn mui-btn-outlined">立即体验</button>
</div>
</div>
</div>
<script src="js/mui.min.js"></script>
<script>
mui.init();
mui.init();
getPicture();
function getPicture() {
var template='';
var btn='';
var slider = mui("#slider");
var gallery=document.getElementById("slider-group")
mui.ajax('http://127.0.0.1/app/home/index.php?r=advertiese/get-home-ad',{
dataType:'json',//服务器返回json格式数据
type:'get',//HTTP请求类型
timeout:10000,//超时时间设置为10秒;
success:function(data){
console.log(JSON.stringify(data));
var ret=data.response;
var result=data.result;
var website='http://10.2.5.76/app/home/';
if (ret==200) {
mui.each(result,function(index,item){
var para=document.createElement("div");
template='<div class="mui-slider-item" style="background-image: url('+website+item.content+');">'
+'</div>';
gallery.innerHTML+=template;
});
btn='<button id="enter" class="mui-btn mui-btn-outlined">'
+"立即体验"
+'</button>';
gallery.innerHTML+=btn;
slider.slider({
interval: 5000
});
enter();
}else{
slider.slider({
interval: 0
});
}
},
error:function(xhr,type,errorThrown){
}
});
}
function enter () {
(function($,doc) {
var enterButton = doc.querySelector('#enter');
enterButton.addEventListener('tap', function(event) {
plus.webview.currentWebview().close();
plus.storage.setItem("guide", plus.runtime.version);
}, false);
$.plusReady(function() {
plus.navigator.closeSplashscreen();
});
}(mui, document));
}
</script>
</body>
</html>
收起阅读 »

slider动态加载
html
<div id="slider" class="mui-slider" style="height:220px;">
<div class="mui-slider-group mui-slider-loop" id="gallery">
</div>
<div class="mui-slider-indicator" id="indicator">
</div>
</div>
js
function Home_slider() {
var first='';
var last='';
var middle='';
var gallerys=document.getElementById("gallery");
var elements=document.getElementById("indicator");
var slider = mui("#slider");
mui.ajax('http://127.0.0.1/app/home/index.php?r=ad/get-home-ad',{
dataType:'json',//服务器返回json格式数据
type:'get',//HTTP请求类型
timeout:10000,//超时时间设置为10秒;
success:function(data){
console.log(JSON.stringify(data));
var ret=data.response;
var result=data.result;
var website='http://127.0.0.1/app/home/';
if (ret==200) {
while(gallerys.hasChildNodes())
{
gallerys.removeChild(gallerys.firstChild);
}
var i=0;
mui.each(result,function(index,item){
i++;
var para=document.createElement("div");
if (i==1) {
para.className='mui-indicator mui-active';
elements.appendChild(para);
first='<div class="mui-slider-item mui-slider-item-duplicate">'
+'<a href="javascript:;">'
+'<img src="'+website+item.content+'">'
+'</a>'
+'</div>';
}else{
para.className='mui-indicator';
elements.appendChild(para);
if (i==4) {
last='<div class="mui-slider-item mui-slider-item-duplicate">'
+'<a href="javascript:;">'
+'<img src="'+website+item.content+'">'
+'</a>'
+'</div>';
}
middle='<div class="mui-slider-item">'
+'<a href="javascript:;">'
+'<img src="'+website+item.content+'">'
+'</a>'
+'</div>';
}
gallerys.innerHTML+=first;
gallerys.innerHTML+=middle;
gallerys.innerHTML+=last;
});
slider.slider({
interval: 5000
});
}else{
slider.slider({
interval: 0
});
}
},
error:function(xhr,type,errorThrown){
}
});
}
html
<div id="slider" class="mui-slider" style="height:220px;">
<div class="mui-slider-group mui-slider-loop" id="gallery">
</div>
<div class="mui-slider-indicator" id="indicator">
</div>
</div>
js
function Home_slider() {
var first='';
var last='';
var middle='';
var gallerys=document.getElementById("gallery");
var elements=document.getElementById("indicator");
var slider = mui("#slider");
mui.ajax('http://127.0.0.1/app/home/index.php?r=ad/get-home-ad',{
dataType:'json',//服务器返回json格式数据
type:'get',//HTTP请求类型
timeout:10000,//超时时间设置为10秒;
success:function(data){
console.log(JSON.stringify(data));
var ret=data.response;
var result=data.result;
var website='http://127.0.0.1/app/home/';
if (ret==200) {
while(gallerys.hasChildNodes())
{
gallerys.removeChild(gallerys.firstChild);
}
var i=0;
mui.each(result,function(index,item){
i++;
var para=document.createElement("div");
if (i==1) {
para.className='mui-indicator mui-active';
elements.appendChild(para);
first='<div class="mui-slider-item mui-slider-item-duplicate">'
+'<a href="javascript:;">'
+'<img src="'+website+item.content+'">'
+'</a>'
+'</div>';
}else{
para.className='mui-indicator';
elements.appendChild(para);
if (i==4) {
last='<div class="mui-slider-item mui-slider-item-duplicate">'
+'<a href="javascript:;">'
+'<img src="'+website+item.content+'">'
+'</a>'
+'</div>';
}
middle='<div class="mui-slider-item">'
+'<a href="javascript:;">'
+'<img src="'+website+item.content+'">'
+'</a>'
+'</div>';
}
gallerys.innerHTML+=first;
gallerys.innerHTML+=middle;
gallerys.innerHTML+=last;
});
slider.slider({
interval: 5000
});
}else{
slider.slider({
interval: 0
});
}
},
error:function(xhr,type,errorThrown){
}
});
}
收起阅读 »

关于html5+定位的有关经验
搞了两天,终于把ios跟android端的定位搞明白了,直接看代码
//定位的代码要写在plusReady()里面,而且不能用mui自带的mui.plusReady(){}
if(window.plus){
plusReady();
}else{
document.addEventListener("plusready",plusReady,false);
}
function plusReady(){
/
android端跟ios端定位的代码是不一样的,要不然获取的地址会不准
/
if(plus.os.name == 'Android'){
var mapObj = new plus.maps.Map('allmap');
var getGPS = mapObj.getUserLocation( function ( state, point ){
if( 0 == state ){
plus.maps.Map.reverseGeocode(point1,{},function(event){
var address = event.address; // 转换后的地理位置
console.log("Address:"+address);
$('#location').text(address);
})
clientPoint.longitude = point.longitude;
clientPoint.latitude = point.latitude;
}else{
}
} );
}
else{
plus.geolocation.getCurrentPosition(function(position){
var point1 = new plus.maps.Point(position.coords.longitude,position.coords.latitude);
clientPoint.longitude = position.coords.longitude;
clientPoint.latitude = position.coords.latitude;
plus.maps.Map.reverseGeocode(point1,{},function(event){
var address = event.address; // 转换后的地理位置
var point = event.coord; // 转换后的坐标信息
var coordType = event.coordType; // 转换后的坐标系类型
console.log("Address:"+address);
$('#location').text(address);
console.log(JSON.stringify(event));
})
}, function ( e ) {
}, {geocode:false} );
}
}
搞了两天,终于把ios跟android端的定位搞明白了,直接看代码
//定位的代码要写在plusReady()里面,而且不能用mui自带的mui.plusReady(){}
if(window.plus){
plusReady();
}else{
document.addEventListener("plusready",plusReady,false);
}
function plusReady(){
/
android端跟ios端定位的代码是不一样的,要不然获取的地址会不准
/
if(plus.os.name == 'Android'){
var mapObj = new plus.maps.Map('allmap');
var getGPS = mapObj.getUserLocation( function ( state, point ){
if( 0 == state ){
plus.maps.Map.reverseGeocode(point1,{},function(event){
var address = event.address; // 转换后的地理位置
console.log("Address:"+address);
$('#location').text(address);
})
clientPoint.longitude = point.longitude;
clientPoint.latitude = point.latitude;
}else{
}
} );
}
else{
plus.geolocation.getCurrentPosition(function(position){
var point1 = new plus.maps.Point(position.coords.longitude,position.coords.latitude);
clientPoint.longitude = position.coords.longitude;
clientPoint.latitude = position.coords.latitude;
plus.maps.Map.reverseGeocode(point1,{},function(event){
var address = event.address; // 转换后的地理位置
var point = event.coord; // 转换后的坐标信息
var coordType = event.coordType; // 转换后的坐标系类型
console.log("Address:"+address);
$('#location').text(address);
console.log(JSON.stringify(event));
})
}, function ( e ) {
}, {geocode:false} );
}
}
收起阅读 »
mui的tap事件封装成anguar指令
ngModule.directive('ngTap', ['$parse',function($parse) {
return {
restrict: 'A',
compile: function($element, attr) {
var fn = $parse(attr["ngTap"]);
return function ngEventHandler(scope, elem) {
elem[0].addEventListener("tap",function(e){
var callback = function(e) {
fn(scope, {$event:e});
};
scope.$apply(callback);
});
};
}
};
}]);
ngModule.directive('ngTap', ['$parse',function($parse) {
return {
restrict: 'A',
compile: function($element, attr) {
var fn = $parse(attr["ngTap"]);
return function ngEventHandler(scope, elem) {
elem[0].addEventListener("tap",function(e){
var callback = function(e) {
fn(scope, {$event:e});
};
scope.$apply(callback);
});
};
}
};
}]);
收起阅读 »

angualr+mui对<input type="file" />图片上传的onchange事件的封装
angular+mui点击事件无法触发脏检查的问题,通过angular指令对原生js的onchange事件的封装解决这个问题
ngModule.directive('fileInput', ['$parse',function($parse) {
return {
restrict: "EA",
template: "<input type='file'/>",
replace: true,
link: function (scope, element, attrs) {
var modelGet = $parse(attrs.fileInput);
var modelSet = modelGet.assign;
var onChange = $parse(attrs.onChange);
var updateModel = function () {
scope.$apply(function () {
modelSet(scope, element[0].files[0]);
onChange(scope);
});
};
element.bind('change', updateModel);
}
};
}])
angular+mui点击事件无法触发脏检查的问题,通过angular指令对原生js的onchange事件的封装解决这个问题
ngModule.directive('fileInput', ['$parse',function($parse) {
return {
restrict: "EA",
template: "<input type='file'/>",
replace: true,
link: function (scope, element, attrs) {
var modelGet = $parse(attrs.fileInput);
var modelSet = modelGet.assign;
var onChange = $parse(attrs.onChange);
var updateModel = function () {
scope.$apply(function () {
modelSet(scope, element[0].files[0]);
onChange(scope);
});
};
element.bind('change', updateModel);
}
};
}])

【示例】内置浏览器titleNView版
需求简述
在手机应用内,可以访问外部的网站信息。通常用于推广信息以及商城的活动页等。
实现思路
浏览器
WebView是基于手机webkit内核浏览器封装的一个组件,无论是本地的还是网络的html都可以加载,可以将其视作一个浏览器。
html5plus封装了Webview模块,那么基本的浏览器就有了。
基本操作
浏览器的使用,最基本的操作,大致如下:
- 前进
- 后退
- 刷新
- 关闭
在html5plus环境下,操作的就是WebviewObject。现有的API,完全可以满足这些基本操作。
Webview窗口对象
菜单栏
titleNView是HBuilder8.8更新发布时,html5plus新增的一个与Webview关联的原生组件。
该组件提供了更多的配置,方便进行按钮的布局,并且可以配置进度条等,那么菜单栏就有了。
布局
因为不是真的开发一款浏览器,布局直接从简。功能按钮排布在顶部的titleNView上,剩下的Webview区域用于展示页面内容。
具体实现
创建浏览器
创建Webview直接调用相关API即可,这里就不再详细说明了,关键在于titleNView的配置。
给菜单栏添加按钮
阅读titleNView中标题栏上的自定义按钮相关的API说明,按钮的文本是可以使用unicode字符的。
推荐上Iconfont-阿里巴巴矢量图标库下载所需的矢量图,并将字体文件放在工程目录下。
注意:这里配置icon时,有个需要注意的地方。比如后退箭头,从浏览器中获取的unicode码是"\e603",但是配置的时候,需要填写为"\ue603"才能被原生层正确解析。
buttons: [{ //后退按钮
'float': 'left',
fontSrc: '_www/font/browser.ttf',
text: '\ue603',
onclick: _self.back.bind(_self) //指定函数的上下文为browser,否则是当前这个对象;
}, { //前进箭头
'float': 'left',
fontSrc: '_www/font/browser.ttf',
text: '\ue602',
onclick: _self.forward.bind(_self)
}, { //关闭按钮
'float': 'right',
fontSrc: '_www/font/browser.ttf',
text: '\ue601',
onclick: _self.close.bind(_self)
}, { //刷新按钮
'float': 'right',
fontSrc: '_www/font/browser.ttf',
text: '\ue600',
onclick: _self.reload.bind(_self)
}]
实现按钮功能
打开浏览器
// 显示浏览器
browser.show = function(url) {
url = url || 'http://www.dcloud.io/'; //默认使用DCloud官网
this.webview.loadURL(url);
this.webview.show('slide-in-right');
};
这里采用预加载方案,打开浏览器时,加载目标地址。
前进
// 前进
browser.forward = function() {
var _self = this;
_self.webview.canForward(function(event) {
if(event.canForward) {
_self.webview.forward();
} else {
plus.nativeUI.toast('没有可前进的地址');
}
});
};
首先要检测,是否可以前进。不能前进,就做出相应的提示。
后退
// 后退
browser.back = function() {
var _self = this;
_self.webview.canBack(function(event) {
console.log('event:', event)
if(event.canBack) {
_self.webview.back();
} else {
_self.close();
}
});
};
与前进同理,先检查是否可以后退,然后再执行相关的逻辑。
刷新
// 刷新
browser.reload = function() {
this.webview.reload(true);
};
刷新就很简单了,直接调用相关API即可。
关闭
// 关闭
browser.close = function() {
this.webview.hide('slide-out-right');
this.webview.clear();
};
关闭操作中,由于是使用预加载方案,所以选择隐藏了Webview,然后清空了Webview中加载的内容。
实际开发中,根据实际业务需求进行调整即可。
效果图及源码

下载附件中的文件,直接解压真机运行即可体验。
需求简述
在手机应用内,可以访问外部的网站信息。通常用于推广信息以及商城的活动页等。
实现思路
浏览器
WebView是基于手机webkit内核浏览器封装的一个组件,无论是本地的还是网络的html都可以加载,可以将其视作一个浏览器。
html5plus封装了Webview模块,那么基本的浏览器就有了。
基本操作
浏览器的使用,最基本的操作,大致如下:
- 前进
- 后退
- 刷新
- 关闭
在html5plus环境下,操作的就是WebviewObject。现有的API,完全可以满足这些基本操作。
Webview窗口对象
菜单栏
titleNView是HBuilder8.8更新发布时,html5plus新增的一个与Webview关联的原生组件。
该组件提供了更多的配置,方便进行按钮的布局,并且可以配置进度条等,那么菜单栏就有了。
布局
因为不是真的开发一款浏览器,布局直接从简。功能按钮排布在顶部的titleNView上,剩下的Webview区域用于展示页面内容。
具体实现
创建浏览器
创建Webview直接调用相关API即可,这里就不再详细说明了,关键在于titleNView的配置。
给菜单栏添加按钮
阅读titleNView中标题栏上的自定义按钮相关的API说明,按钮的文本是可以使用unicode字符的。
推荐上Iconfont-阿里巴巴矢量图标库下载所需的矢量图,并将字体文件放在工程目录下。
注意:这里配置icon时,有个需要注意的地方。比如后退箭头,从浏览器中获取的unicode码是"\e603",但是配置的时候,需要填写为"\ue603"才能被原生层正确解析。
buttons: [{ //后退按钮
'float': 'left',
fontSrc: '_www/font/browser.ttf',
text: '\ue603',
onclick: _self.back.bind(_self) //指定函数的上下文为browser,否则是当前这个对象;
}, { //前进箭头
'float': 'left',
fontSrc: '_www/font/browser.ttf',
text: '\ue602',
onclick: _self.forward.bind(_self)
}, { //关闭按钮
'float': 'right',
fontSrc: '_www/font/browser.ttf',
text: '\ue601',
onclick: _self.close.bind(_self)
}, { //刷新按钮
'float': 'right',
fontSrc: '_www/font/browser.ttf',
text: '\ue600',
onclick: _self.reload.bind(_self)
}]
实现按钮功能
打开浏览器
// 显示浏览器
browser.show = function(url) {
url = url || 'http://www.dcloud.io/'; //默认使用DCloud官网
this.webview.loadURL(url);
this.webview.show('slide-in-right');
};
这里采用预加载方案,打开浏览器时,加载目标地址。
前进
// 前进
browser.forward = function() {
var _self = this;
_self.webview.canForward(function(event) {
if(event.canForward) {
_self.webview.forward();
} else {
plus.nativeUI.toast('没有可前进的地址');
}
});
};
首先要检测,是否可以前进。不能前进,就做出相应的提示。
后退
// 后退
browser.back = function() {
var _self = this;
_self.webview.canBack(function(event) {
console.log('event:', event)
if(event.canBack) {
_self.webview.back();
} else {
_self.close();
}
});
};
与前进同理,先检查是否可以后退,然后再执行相关的逻辑。
刷新
// 刷新
browser.reload = function() {
this.webview.reload(true);
};
刷新就很简单了,直接调用相关API即可。
关闭
// 关闭
browser.close = function() {
this.webview.hide('slide-out-right');
this.webview.clear();
};
关闭操作中,由于是使用预加载方案,所以选择隐藏了Webview,然后清空了Webview中加载的内容。
实际开发中,根据实际业务需求进行调整即可。
效果图及源码
下载附件中的文件,直接解压真机运行即可体验。
收起阅读 »
HBuilder8.8.0中vue.js代码提示功能介绍
> 本文为老HBuilder的介绍。新版HBuilderX自带超强vue支持,详见:https://ask.dcloud.net.cn/docs/#//ask.dcloud.net.cn/article/19601
如何引入
框架语法提示引入方式有两种:
- 如果项目中存在vue.xxx.js文件或者html中script标签引用了vue,则会自动挂载vue语法提示。
- 如果(1)中的条件不满足,则需要手动挂载(在项目上点右键选择【引入框架语法提示】,在框架列表中勾选上vue)
功能介绍
- vue基本API的提示
- 构造vue实例时的配置项参数提示
- vue指令提示
- vue自定义组件标签在html中的提示
- el以及template属性内智能提示
> 本文为老HBuilder的介绍。新版HBuilderX自带超强vue支持,详见:https://ask.dcloud.net.cn/docs/#//ask.dcloud.net.cn/article/19601
如何引入
框架语法提示引入方式有两种:
- 如果项目中存在vue.xxx.js文件或者html中script标签引用了vue,则会自动挂载vue语法提示。
- 如果(1)中的条件不满足,则需要手动挂载(在项目上点右键选择【引入框架语法提示】,在框架列表中勾选上vue)
功能介绍
- vue基本API的提示
- 构造vue实例时的配置项参数提示
- vue指令提示
- vue自定义组件标签在html中的提示
- el以及template属性内智能提示

微信支付,调用返回-1
1.在后台生成的签名,必须是生成预支付id后再次生成的签名
2.APP内json配置支付appid必须与商户内生成的id一致
- 必须用自己的证书打包后,才能正常调用
4.调用微信支付的时候参数顺序appid: resObj.data.appid, noncestr: resObj.data.noncestr, package: resObj.data.package, partnerid: resObj.data.partnerid, prepayid: resObj.data.prepayid, timestamp: resObj.data.timestamp, sign: resObj.data.sign
5.timestamp 类型为number
1.在后台生成的签名,必须是生成预支付id后再次生成的签名
2.APP内json配置支付appid必须与商户内生成的id一致
- 必须用自己的证书打包后,才能正常调用
4.调用微信支付的时候参数顺序appid: resObj.data.appid, noncestr: resObj.data.noncestr, package: resObj.data.package, partnerid: resObj.data.partnerid, prepayid: resObj.data.prepayid, timestamp: resObj.data.timestamp, sign: resObj.data.sign
5.timestamp 类型为number

客户端破解以后,我们怎么解决,赤裸裸的数据交互解决
环境前提:
1.客户端已被破解可以查看到数据交互的api接口
2.账号密码没有存在本地手机存储内
3.登录密码没有第二个人知道
4.服务器登录有Oauth2.0进行授权登录。没有的需要搭建一个授权服务器。
5.手机已经ROOT,可以获得本机设备id和互联网唯一标识id,还有token。
需要解决的问题集合:
1.担心客户端破解以后所有的api接口都暴露出来有攻击的威胁。
2.账号密码存在本地,被root过手机的恶意程序获得账号密码。
3.获得token以后伪造设备id等唯一标识符操作数据,存在威胁。
4.自动登录的问题怎么解决。
安全解决原理:
解决第1个问题:
第一次登录成功账号,则获得一个授权服务器分配的token,以后所有的数据操作都是用token进行操作。
账号密码没有存在本地,则跟服务通讯的时候需要有一个token(令牌)。
token令牌的生成:则需要登录成功以后获得本地手机的设备ID和互联网唯一标识id来绑定这个token只能在这个手机上面进行操作。如果token被坏人截获,在使用token获取api接口数据的时候则自动验证此token失效,因为token匹配手机的设备ID和互联网唯一标识id变动了。token失效以后需要重新登录才可以获得正确的token,因为坏人不知道账号密码所以没有办法登录,手机端被破解以后,账号密码也没有保存在本地所以也不知道账号密码,有小伙伴就问了第一次登录的时候被截获怎么办,那答案就是登录授权服务器的时候用的是https(ssl)加密协议登录的,所以这个破解的几率还是有一点难度。
注解:客户端被破解出来所有的传递的字段都看到了,api接口的地址也知道了,就会有坏人恶意操作,通过这个token就可以解决第一个问题。
解决第2个问题:
因为是使用的token操作,所有本地不存账号密码这些机密数据,及时手机被root了也获得不了账号密码。只能获得token数据。这个token是唯一的只能在本机使用,如果伪造这个本机的设备id和互联网id,则这个账号可以在别的设备上登录,前提是别的设备的编号要可以伪造。
解决第3个问题:
退3步说话,如果token被别人获得了,设备id被别人获得了,那别人就可以伪造id和使用token来操作数据了,是的,这怎么办?你获取的数据基本都是这个token用户的数据,其他的用户你威胁不了,至少区域给你限制住了,ok,继续看下一步,如果你恶意刷新获取服务器公共资源数据,那管理员直接在授权服务器授权每个用户获取公共资源每天的次数限制一下即可,你恶意获取次数是有限的,如果获得这个用户的token修改密码怎么办,好办,在更改密码的时候验证手机号短信即可,验证成功则可以修改密码,验证不成功则不能修改密码。涉及到资金交易的,只需要设置每笔资金交易有交易密码就OK,用token交易的时候没有交易密码也是白扯。
解决第4个问题:
直接传递token去服务器验证即可,验证通过就登录成功,验证不通过就显示登录账户密码进行登录。
收集各位小宇宙的猜想,看看还有什么攻击我没想到,还有什么问题我没解决,大家一起来解决,一起来猜想,多多交流!
环境前提:
1.客户端已被破解可以查看到数据交互的api接口
2.账号密码没有存在本地手机存储内
3.登录密码没有第二个人知道
4.服务器登录有Oauth2.0进行授权登录。没有的需要搭建一个授权服务器。
5.手机已经ROOT,可以获得本机设备id和互联网唯一标识id,还有token。
需要解决的问题集合:
1.担心客户端破解以后所有的api接口都暴露出来有攻击的威胁。
2.账号密码存在本地,被root过手机的恶意程序获得账号密码。
3.获得token以后伪造设备id等唯一标识符操作数据,存在威胁。
4.自动登录的问题怎么解决。
安全解决原理:
解决第1个问题:
第一次登录成功账号,则获得一个授权服务器分配的token,以后所有的数据操作都是用token进行操作。
账号密码没有存在本地,则跟服务通讯的时候需要有一个token(令牌)。
token令牌的生成:则需要登录成功以后获得本地手机的设备ID和互联网唯一标识id来绑定这个token只能在这个手机上面进行操作。如果token被坏人截获,在使用token获取api接口数据的时候则自动验证此token失效,因为token匹配手机的设备ID和互联网唯一标识id变动了。token失效以后需要重新登录才可以获得正确的token,因为坏人不知道账号密码所以没有办法登录,手机端被破解以后,账号密码也没有保存在本地所以也不知道账号密码,有小伙伴就问了第一次登录的时候被截获怎么办,那答案就是登录授权服务器的时候用的是https(ssl)加密协议登录的,所以这个破解的几率还是有一点难度。
注解:客户端被破解出来所有的传递的字段都看到了,api接口的地址也知道了,就会有坏人恶意操作,通过这个token就可以解决第一个问题。
解决第2个问题:
因为是使用的token操作,所有本地不存账号密码这些机密数据,及时手机被root了也获得不了账号密码。只能获得token数据。这个token是唯一的只能在本机使用,如果伪造这个本机的设备id和互联网id,则这个账号可以在别的设备上登录,前提是别的设备的编号要可以伪造。
解决第3个问题:
退3步说话,如果token被别人获得了,设备id被别人获得了,那别人就可以伪造id和使用token来操作数据了,是的,这怎么办?你获取的数据基本都是这个token用户的数据,其他的用户你威胁不了,至少区域给你限制住了,ok,继续看下一步,如果你恶意刷新获取服务器公共资源数据,那管理员直接在授权服务器授权每个用户获取公共资源每天的次数限制一下即可,你恶意获取次数是有限的,如果获得这个用户的token修改密码怎么办,好办,在更改密码的时候验证手机号短信即可,验证成功则可以修改密码,验证不成功则不能修改密码。涉及到资金交易的,只需要设置每笔资金交易有交易密码就OK,用token交易的时候没有交易密码也是白扯。
解决第4个问题:
直接传递token去服务器验证即可,验证通过就登录成功,验证不通过就显示登录账户密码进行登录。
收集各位小宇宙的猜想,看看还有什么攻击我没想到,还有什么问题我没解决,大家一起来解决,一起来猜想,多多交流!

分享如何将mui.js整合进vue项目
具体vue项目创建不介绍了,你可以按照你的心情创建单/多入口文件的vue项目。
重点是如何整合mui.js
大神自有办法,不用我置喙,这里主要写给想用vue,又想把时间花费在业务上的小伙伴。
打包工具用的webpack。这里示例用的是SPA单页面文件,其实没有影响,随你心情
第一步,配置webpack
module.exports = {
entry: {
app: './src/main.js'
},
output: {
...
},
externals: {
mui: 'mui'
},
.....
如果像我一样单页面,只有一个index.html。直接可以用html打包插件,
new HtmlWebpackPlugin({
filename: 'index.html',
template: 'index.html',
inject: true
}),
第二步 正常编写基础逻辑
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>jmapp</title>
<link rel="stylesheet" href="http://dev.dcloud.net.cn/mui/dist/css/mui.min.css">
</head>
<body>
<div id="app"></div>
<!-- built files will be auto injected -->
<script src="http://dev.dcloud.net.cn/mui/dist/js/mui.min.js">
</script>
<script>
mui.init();
mui.plusReady(function() {
});
</script>
</body>
</html>
第三部,vue工程里正常直接使用,无须引用
methods: {
login() {
if (this.user.length < 1) {
mui.alert("roshan")
}
}
}
说到底就是
externals: {
mui: 'mui'
},
只有这一句话有作用。
因为mui使用了匿名递归不能直接require 自然也不能用amd方式加载到es6代码中,vue的严格模式下会报错。
变通方法就是自己引入。。。。。。
希望mui源码转向es6版本。
具体vue项目创建不介绍了,你可以按照你的心情创建单/多入口文件的vue项目。
重点是如何整合mui.js
大神自有办法,不用我置喙,这里主要写给想用vue,又想把时间花费在业务上的小伙伴。
打包工具用的webpack。这里示例用的是SPA单页面文件,其实没有影响,随你心情
第一步,配置webpack
module.exports = {
entry: {
app: './src/main.js'
},
output: {
...
},
externals: {
mui: 'mui'
},
.....
如果像我一样单页面,只有一个index.html。直接可以用html打包插件,
new HtmlWebpackPlugin({
filename: 'index.html',
template: 'index.html',
inject: true
}),
第二步 正常编写基础逻辑
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>jmapp</title>
<link rel="stylesheet" href="http://dev.dcloud.net.cn/mui/dist/css/mui.min.css">
</head>
<body>
<div id="app"></div>
<!-- built files will be auto injected -->
<script src="http://dev.dcloud.net.cn/mui/dist/js/mui.min.js">
</script>
<script>
mui.init();
mui.plusReady(function() {
});
</script>
</body>
</html>
第三部,vue工程里正常直接使用,无须引用
methods: {
login() {
if (this.user.length < 1) {
mui.alert("roshan")
}
}
}
说到底就是
externals: {
mui: 'mui'
},
只有这一句话有作用。
因为mui使用了匿名递归不能直接require 自然也不能用amd方式加载到es6代码中,vue的严格模式下会报错。
变通方法就是自己引入。。。。。。
希望mui源码转向es6版本。
收起阅读 »