優點:css
可快速迭代更新,無須App審覈html
體驗流暢,畢竟是原生前端
減小開發成本,客戶端和前端公用一套代碼web
理解webviewajax
一個小型的瀏覽器內核,能夠加載html網頁,顯示網頁,是app中的一個組件後端
具體實現跨域
前端作好靜態頁面(html、js、css),將文件交給客戶端,通常是放在服務器上,提供一個服務器地址給客戶端瀏覽器
客戶端拿到前端靜態頁面、以文件的形式存儲在app中安全
客戶端在webview中使用file協議加載靜態頁面bash
hybrid 更新上線流程
主要打開app,回去服務端動態進行版本號對比,若是不同,app會彈出提示用戶更新,下載最新的包
前端乾的活,維護服務端更新的靜態資源包(html js css)
前端 服務端 客戶端 三者協調
前端 客戶端 如何通訊
html js css 在手機上作的事情頗有限,不少功能都須要app原生來作
微信公開開放給開發者的客戶端能力,讓js有能力操做手機的功能(js_sdk)
前端開發只須要調動js便可
好比一個新聞詳情頁面,前端如何獲取內容
不能用ajax獲取,第一跨域,第二速度慢
客戶端獲取新聞內容,前端js回調拿到內容再渲染
客戶端能夠在點擊的同時獲取數據(prefetch)
js必須在html頁面渲染完成才能經過ajax獲取數據
schema 協議
重用的協議有 http https ftp SMTP
file協議:本地文件,快
http(s)協議:網絡加載、慢
前端調用客戶端能力 - schema協議
協議規則:
微信的協議 (前面的協議名稱能夠自定義)
定義好之後,前端的js就能夠和後端進行通訊了
var iframe = docuemnt.createElement('iframe')
iframe.style.display = 'none'
iframe.src='weixin://dl/scan' //iframe 會訪問微信的scan功能
var body = document.body || document.getElementByTagName('body')
body.appendChildren(iframe)
setTimeOut( () => {
body.removeChildren(iframe)
iframe = null
})
//若是要加上參數 和 回調函數 callBack,那麼就這樣寫
window['_weixin_scan_callback'] = function(result){
alert(result)
}
iframe.src='weixin://dl/scan?k1=v1&k2=v2&k3=v3&callback=_weixin_scan_callback'
代碼演示:客戶端拿到參數執行對應的函數
function invokeScan() {
window['_invoke_scan_callback_'] = function (result) {
alert(result)
}
var iframe = document.createElement('iframe')
iframe.style.display = 'none'
// iframe.src = 'weixin://dl/scan' // 重要!
iframe.src = 'weixin://dl/scan?k1=v1&k2=v2&k3=v3&callback=_invoke_scan_callback_'
var body = document.body
body.appendChild(iframe)
setTimeout(function () {
body.removeChild(iframe)
iframe = null
})
}複製代碼
schema協議調用封裝成native.js
(function (window, undefined) {
// 調用 schema 的封裝
function _invoke(action, data, callback) {
// 拼裝 schema 協議
var schema = 'myapp://utils/' + action
// 拼接參數
schema += '?a=a'
var key
for (key in data) {
if (data.hasOwnProperty(key)) {
schema += '&' + key+'='+ data[key]
}
}
// 處理 callback
var callbackName = ''
if (typeof callback === 'string') {
callbackName = callback
} else {
callbackName = action + Date.now()
window[callbackName] = callback
}
schema += 'callback=callbackName'
// 觸發
var iframe = document.createElement('iframe')
iframe.style.display = 'none'
iframe.src = schema // 重要!
var body = document.body
body.appendChild(iframe)
setTimeout(function () {
body.removeChild(iframe)
iframe = null
})
}
// 暴露到全局變量
window.invoke = {
share: function (data, callback) {
_invoke('share', data, callback)
},
scan: function (data, callback) {
_invoke('scan', data, callback)
}
login: function (data, callback) {
_invoke('login', data, callback)
}
}
})(window)複製代碼
js代碼調用客戶端能力
document.getElementById('btn1').addEventListener('click', function () {
// invokeScan()
window.invoke.scan({}, function () {})
})
document.getElementById('btn2').addEventListener('click', function () {
window.invoke.share({
title: 'xxx',
content: 'yyy'
}, function (result) {
if (result.errno === 0) {
alert('分享成功')
} else {
alert(result.message)
}
})
})複製代碼
將以上封裝的代碼打包,叫作native.js,內置到客戶端
客戶端每次啓動webview,都默認執行native.js
本地加載,免去網絡加載的時間,速度更快
本地加載,沒有網絡請求,黑客看不到scheme協議、更安全
總結
通信的基本形式:調用能力,傳遞參數、監聽回調
對schema協議的理解和使用
調用schema代碼的封裝