手機的app分爲,在線和單機,在線就是相似於C/S模式,能與服務器與他人共享數據的程序,單機就是在沒有網絡下能夠玩轉的app。php
目前互聯網盛行的時代,99%的程序都是聯網環境下工做的。那麼如何開發本地app而且能經過網絡將數據上傳至服務器共享成爲了在線app的開發重點。css
首先請理解B/S的工做模式,在web程序中,咱們只是向http服務器請求了地址,服務器(不管是apache,tomcat,nginx這些都是實現了http socket的程序)返回給咱們html文件,瀏覽器呢,對html進行解釋,生成可視化的交互界面。html
上面的圖畫的比較簡易,也隱藏了大量的封裝組件,事實上整個過程要比咱們的圖複雜的多,而做爲初級開發者,咱們只須要知道這些,不管是javaee,asp.net MVC,或者php類型網站的建設都有了基本的套路了!前端
筆者以前其實沒有作過app的開發,更加沒有接觸過google的android sdk,雖然略知一二,可是對xml文件配置深深的厭惡感使我始終都不肯意走上原生android的開發html5
筆者這幾年一直作的web開發,從LAMP環境到asp.net再到javaee,橫跨三大平臺,兩大操做系統,能夠說是web開發的釘子戶,研究app的開發時,因此帶有html5情結的我天然更加熱衷於發揮html5+的開發能力java
那麼html5開發app和網站開發有什麼區別呢?jquery
能夠說,本質上沒有!你徹底可使用html5開發出與原生媲美的app,在html5不斷優化的將來,html5移動開發必然是大勢所趨,這得益於其快速高效的開發環境,簡單易入門的特色。在線html5 app開發套路且看下圖:android
是否是感受沒變什麼呀?確實,因此說本質上沒什麼區別,這就是爲何大部分網站開發者轉行進入app開發更加的簡單(一天不到的事情),只要你懂html5,js,css3以及些許前端框架就能動手了!css3
等等,請先知道一件事!nginx
跨區請求
即,不在同一個域名下進行數據/文件的傳輸,當你使用瀏覽器瀏覽網頁的時候並不會遇到這種問題,由於瀏覽器是從服務器下同一個域名下獲取html,也是向這個網站返回數據文件的
可是,html5開發的app,文件是放在本地手機的,這是爲了提升訪問體驗,手機不會向服務器請求完整的html文件,這就形成了要跨域交換數據的問題,即手機本地是一個域,服務器是另外一個域!
這有什麼問題嗎?有啊,瀏覽器默認會阻止跨域請求的,沒想到吧?爲何?爲了安全啊!
萬一有人發了一個帖子,帖子連接到別的網站下,而這個連接的js實現了將你在這個網站獲取的我的資料傳送到連接網站的功能,那麼你點進去之後你登錄的我的資料會被另外一個網站獲取,這是不可能的,瀏覽器會使用同源策略阻止這個事情發生,畢竟這太危險了!
同理app請求的網站不該該把本身域的數據發送給另外一個域(你的手機),瀏覽器認爲數據給了別人!
解釋清楚了,那麼咱們須要解決這個「bug」實現app與服務器的通訊,其實默認的mui已經爲咱們解決了這個問題,用hbuilder打包的app並不存在同源策略問題,能夠跨域請求數據,這種事情只會出如今瀏覽器訪問罷了
早期,我在使用jquery mobile開發的時候,因爲沒有hbuilder這樣的基架,不能及時打包app(開發過程都是在手機瀏覽器中測試寫的html文件,每過一個階段,上傳到phonegap打包成本地app)
因此使用jquery mobile的朋友們,也許會遇到這樣的問題,下面網上有一個小辦法解決手機瀏覽器測試app並訪問其餘網站數據,這也是我之前使用的方法:
js以前,jquery.js以後)*/ $(document).on("mobileinit",function(){ //支持域名ajax加載 $.support.cors=true; $.mobile.allowCrossDomainPages=true; $.mobile.pushState=false; });
這樣在手機瀏覽器裏測試h5 app就不成問題了,實際打包成phonegap以後,是不須要的,由於phonegap使用file協議來發送請求,而且自己不會有同源策略
Phonegap wiki裏面說: 」The cross-domain security policy does not affect PhoneGap applications. Since the html files are called by webkit with the file:// protocol, the security policy does not apply.」
可是,根據我前年jquery mobile開發app的經驗,jquery mobile根本不適合app的開發,這裏沒有黑jquery mobile,他自己的特性就是爲wap而生的,就是適合手機頁面開發,不適合打包爲app,由於他沒有完整的打包環境,即很差使用html5+!
且jquery mobile自己也比較臃腫!雖然功能強大,可是卻不涉及5+,不能使用5+的app不是完整的app!因此之後我可能會用jqmobile開發wap頁面,建議放在微信開發當中
app開發請使用mui,用了mui以後,請忘記上面說的各類問題,咱們開門見山,直插主題,作聯網的app!O(∩_∩)O
咱們作聯網app只需知道兩點:
首先咱們使用ajax和服務器進行通信,mui.ajax()能夠作到這一切
其次,數據交換使用json,商業項目請規定好固定的json格式!
使用ajax以前,請先對ajax進行封裝,這樣減小實際項目中代碼量,我是這麼作的:
新建一個app.js,每個頁面都用的公共類庫
ajax的封裝代碼:
HTTP_DOMAIN = "http://192.168.31.130/dashen/public/index.php/app/"; //全局變量,域名以及經常使用路徑
//使用全局進度條 var progress = mui("body").progressbar(); //把通用的ajax請求打包起來 owner.request = function(ctl, act, dataObj, callback) { //全局進度條 callback = callback || $.noop; ctl = ctl; act = act; var url = HTTP_DOMAIN + ctl + "/" + act; mui.ajax(url, { data: dataObj, dataType: 'json', timeout: 5000, type: 'post', beforeSend: function(XMLHttpRequest) { progress.show(); }, complete: function(XMLHttpRequest, textStatus) { progress.hide(); }, success: function(response) { return callback(response); }, error: function(xhr, type, error) { if(type === "timeout") //不可使用plus,須要使用mui的toast mui.toast("鏈接超時,請檢查網絡"); else mui.toast("未知網絡錯誤,找不到服務器了,稍後試試唄"); } });
注意到,咱們找了一些請求的共同點,加載條和網絡錯誤信息,這些都是每個請求都須要的,就沒必要要在每一個頁面從新寫一遍,這就是封裝的意義
其中ajax有一些參數:
beforeSend:發送前的事件,咱們能夠打開加載進度條,使用的是mui自帶的全局進度條
complete:這是ajax結束以後的事件,不論是失敗仍是成功最後會觸發,因此關閉進度條是最合適的
success:請求成功了,這裏的成功是指訪問到了服務器而且服務器執行順利返回了數據,咱們放一個回掉函數,將獲取的json數據回掉,這樣咱們就能夠實現請求以後根據不一樣頁面的不一樣需求執行不一樣的方法
error:這裏統一報錯,使用mui自帶的提示功能
url:這個參數是請求的地址,這裏使用一個全局變量+控制器類名+方法名的形式,以便訪問不一樣的方法,須要的時候只需向request所在的閉包傳入類名,方法名便可
注意開頭的owner是閉包的名稱,這個request方法放在一個js閉包中,防止與外部的同名方法衝突,實現相似於jquery,以下:
function($, owner) { /*閉包中包含的各類公共方法*/ owner.request=function(){}; owner.xxx = function(){}; }(mui, window.app = {}));
如今能夠調用這個已經封裝好ajax的方法了:例
app.request('User', 'checkLogin', {}, function(res) { if(res.status == 1 && res.data.token == state.token) { //若是檢測服務器存在且本地相對應不操做 plus.navigator.closeSplashscreen(); unfullscreen(); app.setUserInfo(res.data); //存儲服務器獲取的我的信息 update_head_info(); //刷新頭部信息 } else { plus.nativeUI.toast(res.info); app.clearToken(); app.toLogin(); } });
最後一個function就是傳入的回掉函數callback
好了,這樣一個聯網的h5 app就這麼簡單的實現了,至於這個封裝ajax的方法還可擴充適應不一樣場合,能夠自行研究修改!
注意:服務器請返回json格式,請放棄古老的xml,給個我用的thinkphp5框架後端的示例:
if($res && $id) return ['status'=>1,'info'=>'註冊成功']; //json else return ['status'=>0,'info'=>'用戶信息寫入錯誤,稍後重試']; //json
這段代碼的前提是,配置thinkphp統一返回json而不是view()
// app的默認輸出都是json,須要按照規範輸出到app客戶端 'default_return_type' => 'json', // 默認AJAX 數據返回格式,可選json xml ... 'default_ajax_return' => 'json',
其餘後端框架,其餘語言請使用各自的json返回配置,方法和函數