:method: POST:scheme: https:authority: vendor-api-prod.gaoying.com:path: /customer/logs/Accept: application/json, text/plain, */*Content-Type: application/x-www-form-urlencoded //表单提交方式Origin: http://h5-vendor-dev.gaoying.comContent-Length: 236Accept-Language: zh-cnHost: vendor-api-dev.gaoying.comUser-Agent: Mozilla/5.0 (iPhone; CPU iPhone OS 13_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148Referer: http://h5-vendor-dev.gaoying.com/page/customerMain.html?customerId=172821&userId=15243265&token=41cadcb70eed35378a92379871a51181Accept-Encoding: gzip, deflate, brConnection: keep-alive
status: 200 Access-Control-Allow-Origin: * Content-Type: application/json;charset=UTF-8 //json 响应格式 Date: Fri, 27 Dec 2019 05:58:18 GMT Server: Tengine
METHODS: [ 'ACL', 'BIND', 'CHECKOUT', 'CONNECT', 'COPY', 'DELETE', 'GET', 'HEAD', 'LINK', 'LOCK', 'M-SEARCH', 'MERGE', 'MKACTIVITY', 'MKCALENDAR', 'MKCOL', 'MOVE', 'NOTIFY', 'OPTIONS', 'PATCH', 'POST', 'PROPFIND', 'PROPPATCH', 'PURGE', 'PUT', 'REBIND', 'REPORT', 'SEARCH', 'SOURCE', 'SUBSCRIBE', 'TRACE', 'UNBIND', 'UNLINK', 'UNLOCK', 'UNSUBSCRIBE' ]
STATUS_CODES: { '100': 'Continue', '101': 'Switching Protocols', '102': 'Processing', '103': 'Early Hints', '200': 'OK', '201': 'Created', '202': 'Accepted', '203': 'Non-Authoritative Information', '204': 'No Content', '205': 'Reset Content', '206': 'Partial Content', '207': 'Multi-Status', '208': 'Already Reported', '226': 'IM Used', '300': 'Multiple Choices', '301': 'Moved Permanently', '302': 'Found', '303': 'See Other', '304': 'Not Modified', '305': 'Use Proxy', '307': 'Temporary Redirect', '308': 'Permanent Redirect', '400': 'Bad Request', '401': 'Unauthorized', '402': 'Payment Required', '403': 'Forbidden', '404': 'Not Found', '405': 'Method Not Allowed', '406': 'Not Acceptable', '407': 'Proxy Authentication Required', '408': 'Request Timeout', '409': 'Conflict', '410': 'Gone', '411': 'Length Required', '412': 'Precondition Failed', '413': 'Payload Too Large', '414': 'URI Too Long', '415': 'Unsupported Media Type', '416': 'Range Not Satisfiable', '417': 'Expectation Failed', '418': "I'm a Teapot", '421': 'Misdirected Request', '422': 'Unprocessable Entity', '423': 'Locked', '424': 'Failed Dependency', '425': 'Unordered Collection', '426': 'Upgrade Required', '428': 'Precondition Required', '429': 'Too Many Requests', '431': 'Request Header Fields Too Large', '451': 'Unavailable For Legal Reasons', '500': 'Internal Server Error', '501': 'Not Implemented', '502': 'Bad Gateway', '503': 'Service Unavailable', '504': 'Gateway Timeout', '505': 'HTTP Version Not Supported', '506': 'Variant Also Negotiates', '507': 'Insufficient Storage', '508': 'Loop Detected', '509': 'Bandwidth Limit Exceeded', '510': 'Not Extended', '511': 'Network Authentication Required'}
HTTPS在 HTTP 与 TCP 之间加入 SSL 层,一个加密/身份验证层,用于安全的 HTTP 数据传输。 它是一个 URI scheme(抽象标识符体系)。SSL 是安全套接层 。它的任务是负责在网络传输层基础上对网络连接进行数据加密。具有校验机制,配备身份证书。客户端利用公钥对数据加密,服务端收到加密数据后 对数据进行解密。
Https 服务器端口是 443, Https 公共密钥采用 RSA 算法加密,证书信息将在请求响应之前回复给客户端。客户端根据证书信息本地做一个安全校验,通过后再允许服务端响应返回数据,否则取消本次请求响应。签名算法:SHA-256 ECDSA
在学习请求之前,需要掌握好 Javascript 语言。最基础的知识首先要了解和掌握变量修饰符,Function 和 Object 对象。
let 是局部变量,非常适合循环的时候。const 是只读变量, 初始化的时候就要赋值,且只能赋值一次。var 是全局变量,全局都可以用。
从上图我们看到有个名为 open 的函数,包含参数、调用者、长度、名字、以及 Proto 对象。该对象里面有 apply 、bind、 call 函数。还有一个 contructor 构造器。
Function 属性: length、name、prototype。
Function.prototype.apply() //调用一个函数并将其设置为提供的值。 可以将参数作为 Array 对象传递
Function.prototype.bind() //创建一个新函数,该新函数在调用时将其设置为提供的值,并在调用新函数时在提供的任何参数之前添加给定的参数序列。
Function.prototype.call() //调用一个函数并将其设置为提供的值。 可以按原样传递参数。
Function.prototype.toString() //返回表示函数源代码的字符串。
//题外话,apply 和 bind 增强代码的扩展性,类似 iOS 的 category;
动态改变 this 的指向,也就是 this 从 callObject 动态切换为 thisArg。
callObject.method.apply(thisArg,thisArray),可以将 thisArray 转化为 arguments,传入到 callObject.method 内部。
我们通过以下代码来测试 bind 的用法:
//程序员的黄金年龄 18 ~ 35var checkProgramerAgeRange = function (value) { if (typeof value !== 'number') return false; else return value >= this.minimum && value <= this.maximum;}let programmerRange = { minimum: 18, maximum: 35 };// 把函数内部的 this 修改为 range 对象,let boundCheckProgramerAgeRange = checkProgramerAgeRange.bind(programmerRange);console.log(boundCheckProgramerAgeRange(12));
Object 继承 Function,扩展了自己的许多方法。
Object 的属性构造器 Object.prototypeObject.assign() 将所有可枚举的自身属性的值从一个或多个源对象复制到目标对象。Object.create() 用指定的原型对象和属性创建一个新对象。Object.defineProperty() 定义一个 property 给指定对象Object.defineProperties() 定义一个属性 给指定对象Object.entries() 返回一个装有 map 的数组。Object.getOwnPropertyNames() 得到这个对象自己的属性名Object.getPrototypeOf() 得到指定类型的属性Object.is() 比较对象Object.keys() 字符窜属性Object.values()
let stuObj = {room:"english"};Object.defineProperties(stuObj,{ stuName:{ value:"qiugaoying", writable:true /* configurable, enumerable, value, writable, get, set */ }, age: { value:18, writable:true }})//可直接覆盖某对象的属性;Object.defineProperty(stuObj,"stuName",{ value:"gaogao", writable: true})stuObj.age = 20;console.log(stuObj.stuName); //gaogaoconsole.log(stuObj.age); //20console.log(Object.keys(stuObj)); //room 取得公共属性console.log(Object.values(stuObj)); //room 取得公共属性值console.log(Object.getOwnPropertyNames(stuObj)); //room,age,stuName 取得对象所有属性console.log(Object.getOwnPropertyDescriptors(stuObj)); //获取属性描述器console.log(stuObj["stuName"]); //gaogao
function Person(name,age){ this.name = name; this.age = age;}//通过函数的 prototype 公共空间存储方法Person.prototype.introduce = function(){ console.log("hello,my name is "+this.name);}new Person().introduce();
class Person{ constructor(name,age){ this.name = name; this.age = age; } introduce(){ console.log("我的名字是:"+this.name); }}
类的本质是对象,对象继承 Function。所以 introduce 方法还是存储在 prototype 公共空间中。操作类函数也可通过 Person.prototype 去动态新增新的方法。另外要注意一点类的所有实列共享原型的 prototype。
let student = new Person("qiugaoying",18);let student2 = new Person("lihua",22); console.log(student.__proto__ == student2.__proto__); //结果为 true。 类的所有实列共享原型的 prototype
通常,发起一个请求,需要传入基础参数,业务 url, 业务参数,设置请求头,和响应方式。 接着对响应成功和失败的处理;前端通常的请求方式有 表单提交,Ajax 异步请求,jquery 也提供了 ajax 封装的快捷 api。另外也有较新的框架 Axios。
ajax 的出现是解决局部数据刷新的问题。可通过后台异步调用接口实现页面局部刷新。浏览器原生有个 XMLHttpRequest 对象。 jquery 出来之后,ajax 的调用简化了好多。
$ajax({ type: 'POST', dataType: 'json', //服务端返回的数据类型 contentType: 'application/json' ,//参数类型 url : "http://127.0.0.1/log/list/", headers:{'Content-Type':'application/json'},//请求头, 内容编码类型 默认 "application/x-www-form-urlencoded" data: JSON.stringify({"name":"qiugaoying"}), //传参 success: function(result,status,xhr){ console.log(result); //获取结果 }, error: function (xhr,status,error){ console.log(error); } });
Axios 是一个基于 promise 的 HTTP 库。也可以用在浏览器和 node.js 中。我们来观察一下在 axios 的 api 方法。
//构建一个 axios 实列只读变量,设置基础 urlconst http = axios.create({ baseURL: 'https://vendor-api-prod.qiugaoying.com', timeout: 1000, transformRequest: [function(data) { // Do whatever you want to transform the data let ret = '' for (let it in data) { ret += encodeURIComponent(it) + '=' + encodeURIComponent(data[it]) + '&' } return ret }]});
对请求的基础参数做一个封装。 大部分请求都需要带上一些基础参数和 userId、token 等字段。最后对所有字段 key 排序,最后转成 json 字符串再加密。以下为示例:
const netManager = { getRequestParams: function(params) { let userId = localStorage.getItem("userId"); let token = localStorage.getItem("token"); // var userInfo = JSON.parse(userInfoStr); var obj = Object.assign(params, { api_version: 1, //接口版本 platform: 2, //平台类型 terminal: 1, //终端类型 nonce: (Math.random().toFixed(8) + '').replace('0.', ''), //随机数; timestamp: new Date().getTime(), //当前时间戳 毫秒 user_id:123, //userId token: "ec29c3af0dd998yjhgd22f9y867ws6512", //token version_code: 100 //当前版本号 }); let sign = MD5(this.strKeySort(obj)).toUpperCase(); //md5 加密 obj["Sign"] = sign; return obj; }, //key 排序 strKeySort: function(obj) { const newkey = Object.keys(obj).sort(); const newArr = []; for (let i = 0; i < newkey.length; i++) { if (obj[newkey[i]] === 'undefined' || obj[newkey[i]] === 'null') { obj[newkey[i]] = ''; } newArr.push(`${newkey[i]}=${obj[newkey[i]]}`) } const newStr = newArr.join('&') + '&secret_key=gaoyingAESKey'; return newStr; }, //获取 url 后面带的参数; getUrlKey: function (name) { return decodeURIComponent((new RegExp('[?|&]' + name + '=' + '([^&;]+?)(&|#|;|$)').exec(location.href) || [, ""])[1].replace(/\+/g, '%20')) || null }}
这里拿请求用户个人主页基础信息为样例,把下面方法放入 Vue 的 methods 中。 loading 用的是 weiui.js 框架。以下可以实现一个分页加载的请求:
var vm = new Vue({ el: '#PageContainer1', data: { //分页数据 pageNumber: 1, pageSize: 10, gyPageListStart: 0, hasMoreDataFlag: false, dataSource: [], }, methods: { execBaseCustomerRequest: function(url, listKey) { var loading = null; if (this.pageNumber == 1) { loading = weui.loading('加载中'); } let pageVue = this; //this 在不同的作用域中指向的对象不同;临时存储 vue 对象 if (this.pageNumber == 1) { this.gyPageListStart = 0; } http.post(url, netManager.getRequestParams({ customer_id: this.customerId, start: this.gyPageListStart, size: 10, })).then(function(response) { if (loading) { loading.hide(); } let dataDic = response.data; if (dataDic.status == 1) { var arr = pageVue.dataSource; if (pageVue.pageNumber == 1) { arr = []; } var dataArr = dataDic.data[listKey]; arr = arr.concat(dataArr); pageVue.gyPageListStart = dataDic.data.start; vm.$data.hasMoreDataFlag = (dataDic.data.more == 1); vm.$data.dataSource = arr; } setTimeout(function() { pageVue.requestLoadingFinished = true; }, 800); //重置加载完成的状态; }).catch(function(error) { console.log(error); }); } }});
其他: url 通常会放到一个全局文件中配置
const gaoyingAPI = { customerList: "/customer/list/", customerLogs: "/customer/logs/", customerCoupons: "/customer/coupons/", customerOrders: "/customer/orders/", customerDetail: "/customer/detail/"}
从上文中,我们看到 http 发送 post 方法请求之后,通过 promise 语法 then 的回调监听响应结果,通过 catch 方法 来捕捉异常错误处理。ES6 就支持了 Promise 的用法。Promise 中文为承诺。有三种状态:pending (进行中)、fulfilled (已成功)、rejected (已失败)。 即状态一旦更改就不能再次改变赋值。这也是承诺的意义。Promise 实列通过 then 方法或者 catch 方法 返回一个新的 Promise 实例来实现链式调用。then 方法可以返回普通值或者一个新的 promise。不设置返回值时,默认返回 null。Promise 有很多用法,但什么情况下需要用到 Promise 呢? 在需要处理异步耗时任务的时候,可用 Promise 包装后进行返回。Promise 用的时候会遇到很多种情况,Promise 也提供了对应的解决方法。
//Promise then 嵌套 方式一new Promise(resolve => { console.log("step1:异步请求处理耗时任务"); setTimeout(() => { resolve("qiu"); }, 1000);}).then(value => { //第一个接口请求成功拿到 qiu console.log("step1-result:" + value); return new Promise(resolve => { console.log("step2-1:异步请求处理耗时任务 2"); setTimeout(() => { resolve("qiugao"); }, 1000); //触发第二个接口请求 }).then(value => { //第二个接口请求成功,拿到 id2 做第一件事情。 console.log("step2-1-result-event1:" + value); return "qiugaoying"; }).then(value => { //第二个接口请求成功,拿到 id2 做第二件事情。 console.log("step2-1-result-event2:" + value); return "hello, my name is qiugaoying"; });}).then(value => { //最后全部请求完成,触发汇总刷新。 console.log("step1-result:" + value);});/*console 输出结果:step1:异步请求处理耗时任务step1-result:qiustep2-1:异步请求处理耗时任务 2step2-1-result-event1:qiugaostep2-1-result-event2:qiugaoyingstep1-result:hello, my name is qiugaoying*///Promise then 嵌套,方式二: 把 then 移到同一级展开。执行打印结果是一样的。new Promise(resolve => { console.log("step1:异步请求处理耗时任务"); setTimeout(() => { resolve("qiu"); }, 1000);}).then(value => { //第一个接口请求成功拿到 qiu console.log("step1-result:" + value); return new Promise(resolve => { console.log("step2-1:异步请求处理耗时任务"); setTimeout(() => { resolve("qiugao"); }, 1000); //触发第二个接口请求 });}).then(value => { //第二个接口请求成功,拿到 id2 做第一件事情。 console.log("step2-1-result-event1:" + value); return "qiugaoying";}).then(value => { //第二个接口请求成功,拿到 id2 做第二件事情。 console.log("step2-1-result-event2:" + value); return "hello, my name is qiugaoying";}).then(value => { //最后全部请求完成,触发汇总刷新。 console.log("step1-result:" + value);});
new Promise(resolve => { console.log("step1:异步请求处理耗时任务"); setTimeout(() => { resolve("qiu"); }, 1000); }).then(value => { //第一个接口请求成功拿到 qiu console.log("step1-result:" + value); return new Promise(resolve => { console.log("step2-1:异步请求处理耗时任务"); setTimeout(() => { resolve("qiugao"); }, 1000); //触发第二个接口请求 }); }).then(value => { //第二个接口请求成功,拿到 id2 做第一件事情。 let hasError = true if (hasError) { throw new Error("step2-1-result-event1-error 报异常"); //抛出异常 将不再继续执行 then, 直接到 catch 异常;中途如果没有遇到 catch 将直接到最后的 catch. } else { console.log("step2-1-result-event1:" + value); return "qiugaoying"; } }) /*.catch(err => { console.log("中途 catchError 会继续往下走:" + err); return "qiugaoying" //也会返回一个 promise 实例,并且是 resolved 状态,不会被最后一个 catch 捕捉 })*/ .then(value => { //第二个接口请求成功,拿到 id2 做第二件事情。 console.log("step2-1-result-event2:" + value); return "hello, my name is "+value; }).then(value => { //最后全部请求完成,触发汇总刷新。 console.log("step1-result:" + value); }).catch(error => { console.log("end error:" + error); });
testPromiseAll() { function washFood(){ console.log('做饭第一步:洗菜'); let hasError = false; if(hasError){ return "发现了一只虫子!洗掉它。"; }else{ return '菜洗干净了。'; } } function cutFood() { console.log('做饭第二步:切菜'); var p = new Promise(function (resolve, reject) { //做一些异步操作 setTimeout(function () { let cutFoodHasError = true; //控制默契切菜时 是否发生异常 if(cutFoodHasError){ reject("呜呜~ 割到手了,流血!") }else{ resolve('切好了菜。'); } }, 1000); }) /* 试试打开这里的注释 .catch(error=>{ console.log("切菜异常:"+error); //异常本身就是返回 resolve 状态,值是 null console.log("用创口贴止血,继续做菜。"); }); */ return p; } function cooking() { console.log('做饭第三步:炒菜'); var p = new Promise(function (resolve, reject) { //做一些异步操作 setTimeout(function () { resolve('菜已做好!'); }, 2000); }); return p; } //数组里,如果放 Promise 一定要返回状态。 Promise.all([washFood(), cutFood(),cooking()]) .then((result) => { console.log('上桌,吃饭了:'+result); console.log(result); }).catch(error=>{ console.log("菜没做成,出现了小事故:"+error); }) /* 结果: 1. 当 cutFoodHasError = true;打印如下结果: 菜没做成,出现了小事故:呜呜~ 割到手了,流血! 2. 当 cutFoodHasError = true 且 cutFood 方法里的 Promise 有异常捕捉时: 切菜异常:呜呜~ 割到手了,流血! 上桌,吃饭了:菜洗干净了!,,菜已做好 3. 当 cutFoodHasError = false 上桌,吃饭了:菜洗好了。切好了菜。菜已做好! */ /* Promise.all 使用总结: 数组里可以是 Promise 对象,也可以是别的值,只有 Promise 会等待状态改变 当所有的子 Promise 都完成,该 Promise 完成,返回值是全部值得数组 有任何一个失败,该 Promise 失败,返回值是第一个先失败的子 Promise 结果 */},
//打印结果: 兔子赢了testPromiseRace() { function rabbit() { console.log('兔子选手'); var p = new Promise(function (resolve, reject) { setTimeout(function () { resolve('兔子赢了'); }, 1000); }) .catch(error=>{ console.log("兔子跑步中出现异常:"+error); }); return p; } function tortoise() { console.log('乌龟选手'); var p = new Promise(function (resolve, reject) { setTimeout(function () { resolve('乌龟赢了'); }, 3000); }); return p; } Promise.race([rabbit(),tortoise()]) .then((result) => { console.log("比赛结果:"+result); })}
在 vue 的基础上,我们可以通过 vue cli 来管理我们的项目。vue cli 方式的优势在于模块之间可以很好地相互引用,通过 package 包来管理配置相关的框架依赖。生态非常丰富,可轻松运用 vue-router 来解决路由跳转等问题。首先第一步是要创建一个 vue cli 项目。
npm install -g @vue/clivue create helloworld 方式创建项目也可以使用 GUI vue ui 来通过网页手动点击按钮操作来创建项目
{ "name": "gaoying-cli", "version": "0.1.0", "private": true, "scripts": { "serve": "vue-cli-service serve", "build": "vue-cli-service build", "lint": "vue-cli-service lint" }, "dependencies": { "animate.css": "^3.7.2", "core-js": "^3.4.3", "vue": "^2.6.10", "vue-axios": "^2.1.5", "vue-router": "^3.1.3", "vuex": "^3.1.2", "weui.js": "^1.2.1" }, "devDependencies": { "@vue/cli-plugin-babel": "^4.1.0", "@vue/cli-plugin-router": "^4.1.1", "@vue/cli-plugin-vuex": "^4.1.1", "@vue/cli-service": "^4.1.0", "axios": "^0.19.0", "vue-template-compiler": "^2.6.10", "weui": "^2.1.3" }, "eslintConfig": { "root": true, "env": { "node": true }, "extends": [ "plugin:vue/essential", "eslint:recommended" ], "parserOptions": { "parser": "babel-eslint" } }, "browserslist": [ "> 1%", "last 2 versions" ]}
import Vue from 'vue'import App from './App.vue'import router from './router'import store from './store'import axios from 'axios' //请求网络import VueAxios from 'vue-axios' import weui from 'weui.js' //weuiJsimport 'weui' //weui 样式import ymAPI from '@/assets/js/urlConfig.js' //Apiimport netManager from '@/assets/js/netManager.js' //请求基础参数拼接import ymNativeBridge from '@/assets/js/ymNativeBridge.js' //原生事件交互import animate from 'animate.css'const ymHttp = axios.create({ baseURL: 'https://vendor-api-prod.gaoying.com', timeout: 1000, transformRequest: [function(data) { // Do whatever you want to transform the data let ret = '' for (let it in data) { ret += encodeURIComponent(it) + '=' + encodeURIComponent(data[it]) + '&' } return ret }]});Vue.config.productionTip = falseVue.prototype.$weui = weuiVue.prototype.$ymAPI = ymAPIVue.prototype.$netManager = netManagerVue.prototype.$ymNativeBridge = ymNativeBridgeVue.use(VueAxios, ymHttp,animate)new Vue({ router, store, render: h => h(App)}).$mount('#app');
//和普通 h5 请求网络类似,唯一不同的就是通过挂载到 Vue 上的 axios ,可以通过 this.http 获取。this.netManager 也类似。
execBaseCustomerRequest: function(url, listKey) { var loading = null; if (this.pageNumber == 1) { loading = this.$weui.loading('加载中'); this.gyPageListStart = 0; } let pageVue = this; // this 在不同的作用域中指向的对象不同;临时存储 vue 对象 this.$http.post(url, this.$netManager.getRequestParams({ customer_id: this.customerId, start: this.gyPageListStart, size: 10, })).then(function(response) { if (loading) { loading.hide(); } let dataDic = response.data; if (dataDic.status == 1) { var arr = pageVue.dataSource; if (pageVue.pageNumber == 1) { arr = []; } var dataArr = dataDic.data[listKey]; arr = arr.concat(dataArr); pageVue.gyPageListStart = dataDic.data.start; pageVue.hasMoreDataFlag = (dataDic.data.more == 1); pageVue.dataSource = arr; }else{ pageVue.$weui.topTips(dataDic.errorMsg); } setTimeout(function() { pageVue.requestLoadingFinished = true; }, 800); //重置加载完成的状态; }).catch(function(error) { console.log(error); });}
import MD5 from './md5.js'export default { getRequestParams: function(params) { let userId = localStorage.getItem("userId"); let token = localStorage.getItem("token"); ...... }}//md5.js 文件中 var MD5 = function (string) { ......}module.exports = MD5//接口配置 urlConfig.js 文件中const ymAPI = { //客户信息 customerList: "/customer/list/", customerLogs: "/customer/logs/", customerCoupons: "/customer/coupons/", customerOrders: "/customer/orders/", customerDetail: "/customer/detail/"}module.exports = ymAPI
export 在 js 文件中可以有多个。
//testExport.jsexport const person = { name: "qiugaoying",sex:1, job:"software Programmer"}export const addressInfo = {province:"广东省", city:"guangzhou"}export const introduct = function(){ console.log("my name is qiugaoying");}
export 有多个的时候 ,导入必须用花括号括起来。
import {person,addressInfo} from "../../utils/testExport.js"import * as allExp from "../../utils/testExport.js" //加载全部 export,取个别名
** 总结 **
//原生调用 appexport default { callApp:function(handlerMethod, parameters) { if (!window.WeixinJSBridge || !WeixinJSBridge.invoke) { var handlerInterface = 'YunMiaoNative'; var dic = { 'handlerInterface': handlerInterface, 'function': handlerMethod, //调用原生的指令 'parameters': parameters //传递的参数; }; if (/(iPhone|iPad|iPod|iOS)/i.test(navigator.userAgent)) { window.webkit.messageHandlers[handlerInterface].postMessage(dic); } else { //安卓 app.ymAppWebClick(); //dic } } else { //包含微信功能,比如可唤起小程序。 } }, //原生调用 app 并传递参数给 H5 callbackH5: function(handlerMethod, parameters, callbackMethod) { if (!window.WeixinJSBridge || !WeixinJSBridge.invoke) { var handlerInterface = 'YunMiaoH5'; var dic = { 'handlerInterface': handlerInterface, 'function': handlerMethod, //调用原生的指令 'parameters': parameters, //传递的参数; 'callbackMethod': callbackMethod //回调的函数 }; if (/(iPhone|iPad|iPod|iOS)/i.test(navigator.userAgent)) { window.webkit.messageHandlers[handlerInterface].postMessage(dic); } else { //安卓 app.ymAppWebClick(JSON.stringify(dic)); } } else { //包含微信功能,比如可唤起小程序。 } }}
阅读全文: http://gitbook.cn/gitchat/activity/5e146270eb69ea4eda349b34
您还可以下载 CSDN 旗下精品原创内容社区 GitChat App ,阅读更多 GitChat 专享技术内容哦。