mui初级入门教程(三)— html5+ XMLHttpRequest 与mui aja用法详解

文章来源:小青年原创
发布时间:2016-05-29
关键词:mui,html5+,XMLHttpRequest,ajax,懒加载
转载需标注本文原始地址: http://zhaomenghuan.github.io/

写在前面

这是这个系列的的第三篇文章,前面的文章在多个地方(本人github博客、dcloud ask社区、segmentfault)发出来了,很多朋友收藏点赞,只是没有多少人反映内容的深浅,也没有人提出意见,所以实话说不知道符不符合大家胃口,不过我写博客一向以详细为标准,尽可能照顾到各种人群,特别是入门级的同学,力求还原我学习这个东西的一个思路和过程,在文章中也分享一些不错的干货,最近在折腾博客,用webpack和vue-cli打包了一下,目前还有些问题有待解决,自己尝试写一个markdown编辑器因为bug过多的问题,然后开始使用马克飞象写博客,毕竟生成的界面美观多了,这样可以方便大家阅读吧。废话不多说,开始我们今天的内容,今天主要是学习一下html5+的XMLHttpRequest 以及mui的基本用法。

基础铺垫

Javascript XMLHttpRequest网络请求

XMLHttpRequest 是一个 JavaScript 对象,它最初由微软设计,随后被 Mozilla、Apple 和 Google采纳. 如今,该对象已经被 W3C组织标准化. 通过它,你可以很容易的取回一个URL上的资源数据. 尽管名字里有XML, 但 XMLHttpRequest 可以取回所有类型的数据资源,并不局限于XML。 而且除了HTTP ,它还支持file 和 ftp 协议. —— MDN XMLHttpRequest

XMLHttpRequest 让发送一个HTTP请求变得非常容易。你只需要简单的创建一个请求对象实例,打开一个URL,然后发送这个请求。当传输完毕后,结果的HTTP状态以及返回的响应内容也可以从请求对象中获取。

XMLHttpRequest网络请求的一般步骤:

第一步:创建一个 XMLHttpRequest 实例

new XMLHttpRequest();
第二步:初始化HTTP请求参数

void open(
DOMString method,
DOMString url,
optional boolean async,
optional DOMString user,
optional DOMString password
);

  1. method:请求所使用的HTTP方法; 例如 "GET", "POST", "PUT", "DELETE"等. 如果下个参数是非HTTP(S)的URL,则忽略该参数.

  2. url:该请求所要访问的URL

  3. async:一个可选的布尔值参数,默认为true,意味着是否执行异步操作,如果值为false,则send()方法不会返回任何东西,直到接受到了服务器的返回数据。如果为值为true,一个对开发者透明的通知会发送到相关的事件监听者。这个值必须是true,如果multipart属性是true,否则将会出现一个意外。

  4. user:用户名,可选参数,为授权使用;默认参数为空string.

  5. password:密码,可选参数,为授权使用;默认参数为空string.

第三步:发送请求

send();
发送请求. 如果该请求是异步模式(默认),该方法会立刻返回. 相反,如果请求是同步模式,则直到请求的响应完全接受以后,该方法才会返回.

如下例:

var xhr = new XMLHttpRequest();
xhr.onload = function () {
console.log(this.responseText);
};
xhr.onreadystatechange = function() {
console.log(this.readyState);
};
xhr.open("get", "https://www.baidu.com", true);
xhr.send();
我们在hbuilder里面打开,控制台会报错:

[Web浏览器] "XMLHttpRequest cannot load https://www.baidu.com/. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://127.0.0.1:8020' is therefore not allowed access."

用浏览器打开,按F12在控制台console下查看也会发现上述错误,这是为啥呢?

这是因为普通网页能够使用XMLHttpRequest对象发送或者接受服务器数据, 但是它们受限于同源策略。只要先获取了跨域请求许可,就可以进行跨域请求。

同源策略:如果两个页面的协议域名端口是完全相同的,那么它们就是同源的。同源策略是为了防止从一个地址加载的文档或脚本访问或者设置从另外一个地址加载的文档的属性。如果两个页面的主域名相同,则还可以通过设置 document.domain属性将它们认为是同源的。

超级产品经理")
}
};
xhr.onerror = function () {
alert('error making the request.');
};
xhr.send();

哈哈,执行完这段代码你会发现,你能够查看到我博客的列表,所以大家是不是懂了些什么, CORS能否跨域实现需要服务器端支持,我们这里能够收到信息,是因为github上的资源是支持CORS访问的,这和框架无关,很多人以为用了框架就可以跨域,这都是不正确的理解,框架只是封装了一些方法,让我们使用更加方便,能不能跨域还是取决于我们服务器端的访问权限。这里顺便说一下很多人用mui会发现在浏览器端会报错,在app环境能够访问,这是因为mui依赖html5+ XMLHttpRequest网络请求模块,后面会详细讲到。第二种:Jsonp,**只适用于get请求**Jsonp的跨域不是用XMLHttpRequest实现的,而是一个script标签,script是可以跨域的,回调函数作为get参数传入请求里。原理很简单,比如你在A域名请求B域名:1. 在A域名的页面中使用script标签src写成B域名中服务器的URLscript标签是可以跨域的,比如你调用Google Map或Google Analytics时引入的js就是google域名下的。1. 后端程序在最后需要把一段js代码的字符串print出来,这样就可以运行A域名js中写好的callback方法,将要返回的数据放入参数就可以了A域名中的js文件:
function myCallback (data) {    alert(data);}
B域名中服务器

String cb = get('callback');
Int b = '我是数据';
print(' ' + cb + '(' + b + '); ');

后端print数据到页面中后就会这样
myCallback('我是数据');
注:部分引用自segmentfault 的**tychio**的回答。总之,不论是XMLHttpRequest的跨域,还是Jsonp,都是需要请求的网站服务器端提供支持,在愿意分享给你数据的情况下你才能得到。在对方没有提供支持的情况下,你是取不到它的数据的。当然跨域的解决方案有很多种,由于本人没有实践过,没有实践就没有发言权,这里给大家贴一个帖子,自己跨域自行验证,浅谈浏览器端JavaScript跨域解决方法。### html5+ XMLHttpRequest网络请求上面我们花了很大篇幅讲解了JavaScript  XMLHttpRequest对象,而且也简单的讲解了同源策略和跨域请求的常用方法,我们注意到无论是JavaScript  XMLHttpRequest还是jsonp都需要通过服务器端的支持才能实现跨域,另外还有几种也有一定的局限性,所以总还是让人觉得美中不足。html5+提供了一个XMLHttpRequest模块,在APP端很完美的解决了这种问题,而且提供了和JavaScript  XMLHttpRequest对象用法类似的一系列属性方法。由于本文的重在在于讲解html5+ XMLHttpRequest,所以前面的JavaScript  XMLHttpRequest相关的属性方法只是初略介绍了一下,下面重点介绍html5+ XMLHttpRequest模块。#### 适用范围:由于html5+ XMLHttpRequest是一种拓展方案,所以需要底层支持,基于html5+ XMLHttpRequest的方法不能用于非5+环境,如果对这些概念不清楚的欢迎先阅读我之前写的文章**mui初级入门教程(一)— 菜鸟入手mui的学习路线**。我们用hbuilder新建一个app工程,然后运行下面的代码:            document.addEventListener('plusready', function(){                var xhr = new plus.net.XMLHttpRequest();                xhr.onreadystatechange = function () {                    switch ( xhr.readyState ) {                        case 0:                            console.log( "xhr请求已初始化" );                        break;                        case 1:                            console.log( "xhr请求已打开" );                        break;                        case 2:                            console.log( "xhr请求已发送" );                        break;                        case 3:                            console.log( "xhr请求已响应");                            break;                        case 4:                            if ( xhr.status == 200 ) {                                alert( "xhr请求成功:"+xhr.responseText );                            } else {                                console.log( "xhr请求失败:"+xhr.readyState );                            }                            break;                        default :                            break;                    }                }                xhr.open("GET", "https://www.baidu.com/");                xhr.send();            }, false );我们会发现最后弹出了弹框,里面写有百度首页的代码。#### XMLHttpRequest对象:创建一个XMLHttpRequest 对象,对象创建时不触发任何时间和网络请求,需和open,send方法配合使用。var xhr = new plus.net.XMLHttpRequest();xhr.open(method, url);xhr.send();**XMLHttpRequest的属性:**1. **readyState: **HTTP 请求的状态1. **response:** 请求从服务器接收到的响应数据1. **responseText:** 请求从服务器接收到的响应数据(字符串数据)1. **responseType:**请求响应数据response的类型1. **responseXML:** 请求响应的Document对象1. **status:** 服务器返回的HTTP状态代码1. **statusText:** 服务器返回的HTTP状态描述1. **timeout:** 请求服务器的超时时间,单位为毫秒(ms)1. **withCredentials:** 是否支持跨域请求**XMLHttpRequest的方法:**1. **abort: **取消当前响应,关闭连接并且结束任何未决的网络活动1. **getAllResponseHeaders: **获取HTTP响应头部信息1. **getResponseHeader: **获取指定的HTTP响应头部的值1. **open: **初始化HTTP请求参数,例如URL和HTTP方法,但是并不发送请求1. **send:** 发送HTTP请求1. **setRequestHeader:** 指定一个HTTP请求的Header**XMLHttpRequest的事件:**1. **onreadystatechange:** 网络请求状态发生变化事件1. **onloadstart:** 网络请求开始事件1. **onprogress:** 网络请求传输数据事件1. **onabort:** 网络请求取消事件1. **onerror:** 网络请求错误事件1. **onload:** 网络请求成功事件1. **ontimeout:** 网络请求超时事件1. **onloadend:** 网络请求结束事件### mui ajaxmui框架基于htm5plus的XMLHttpRequest,封装了常用的Ajax函数,支持GET、POST请求方式,支持返回json、xml、html、text、script数据类型; 本着极简的设计原则,mui提供了mui.ajax方法,并在mui.ajax方法基础上,进一步简化出最常用的mui.get()、mui.getJSON()、mui.post()三个方法。**mui.ajax( url [,settings] )**1. **url**:请求发送的目标地址1. **settings**:key/value格式的json对象,用来配置ajax请求参数,支持的参数如下:1. **data**:发送到服务器的业务数据;1. **type**:请求方式,目前仅支持'GET'和'POST',默认为'GET'方式;1. **dataType**:预期服务器返回的数据类型;如果不指定,mui将自动根据HTTP包的MIME头信息自动判断;支持设置的dataType可选值:"xml": 返回XML文档1. "html": 返回纯文本HTML信息;1. "script": 返回纯文本JavaScript代码1. "json": 返回JSON数据1. "text": 返回纯文本字符串1. **success**:Type: Functon(Anything data,String textStatus,XMLHttpRequest xhr)请求成功时触发的回调函数,该函数接收三个参数:data:服务器返回的响应数据,类型可以是json对象、xml对象、字符串等;1. textStatus:状态描述,默认值为'success'1. xhr:xhr实例对象1. **error**:Type: Functon(XMLHttpRequest xhr,String type,String errorThrown)请求失败时触发的回调函数;该函数接收三个参数:xhr:xhr实例对象1. type:错误描述,可取值:"timeout", "error", "abort", "parsererror"、"null"1. errorThrown:可捕获的异常对象1. **timeout**:Type: Number,请求超时时间(毫秒),默认值为0,表示永不超时;若超过设置的超时时间(非0的情况),依然未收到服务器响应,则触发error回调;1. **headers**:Type: Object,格式为:{'Content-Type':'application/json'},详情参考html5+ setRequestHeader。**基本格式如下:**

mui.ajax(url,{
data:{
username:'username',
password:'password'
},
dataType:'json',//服务器返回json格式数据
type:'post',//HTTP请求类型
timeout:10000,//超时时间设置为10秒;
success:function(data){
//服务器返回响应,根据响应结果,分析是否登录成功;
...
},
error:function(xhr,type,errorThrown){
//异常处理;
console.log(type);
}
});

**mui.post( url [,data] [,success] [,dataType] )**mui.post()方法是对mui.ajax()的一个简化方法,直接使用POST请求方式向服务器发送数据、且不处理timeout和异常(若需处理异常及超时,请使用mui.ajax()方法)

mui.post('http://server-name/login.php',{
username:'username',
password:'password'
},function(data){
//服务器返回响应,根据响应结果,分析是否登录成功;
...
},'json'
);

**mui.get( url [,data] [,success] [,dataType] )**mui.get()方法和mui.post()方法类似,只不过是直接使用GET请求方式向服务器发送数据、且不处理timeout和异常(若需处理异常及超时,请使用mui.ajax()方法)。如下为获得某服务器新闻列表的代码片段,服务器以json格式返回数据列表:

mui.get('http://server-name/list.php',
{category:'news'},
function(data){
//获得服务器响应
...
},'json'
);

**mui.get( url [,data] [,success] )**mui.getJSON()方法是在mui.get()方法基础上的更进一步简化,限定返回json格式的数据,其它参数和mui.get()方法一致,如上获得新闻列表的代码换成mui.getJSON()方法后,更为简洁,如下:

mui.getJSON('http://server-name/list.php',
{category:'news'},
function(data){
//获得服务器响应
...
}
);

注:初学者肯对于GET与POST的区别不是很清楚,这里不做详细介绍,若要深入了解请查看:GET,POST — 简述## 项目实战我们接着上一篇文章的项目开始进行本节的内容,上一篇我们讲解了html5+ webview的使用方法,并且实现了一个基于父子webview的tab bar切换的案例,我们这次利用网易音乐API接口请求数据,完成我们后续的音乐播放器功能。### API分析网易音乐搜索API:1. **url**:http://s.music.163.com/search/get/1. **type**:"GET"或“POST"  //HTTP请求类型1. 请求参数:**type**: 11. **s**:                               //关键词1. **limit**: 10                    //限制返回结果数为101. **offset**: 0                    //偏移1. **src**: lofter                  //可为空1. **filterDj**: true | false   //可为空1. **callback**:                   //为空时返回json,反之返回jsonp callback由于HTTP请求类型包含get,我们只需要把请求的参数拼接到url里面就可以得到返回的数据,格式为url?key1=value1&key2=value2。在这个例子中我们打开这个网址http://s.music.163.com/search/get/?type=1&limit=5&s=喜欢你,我们会发现一些数据返回了,如下图:![超级产品经理](https://v1cdn.imspm.com/imspm.com超级产品经理2016070401y32dj53xjeh.png)");            document.write("audioUrl:" + audioUrl);        });

我们这里说几个开发者常见的问题:

拼接html字符串

首先打开hello mui里面的模板页面lazyload-image.html,我们打开控制台查看elements,结构如下:

![超级产品经理](https://v1cdn.imspm.com/imspm.com超级产品经理2016070401vm13vmzho0d.jpg)");    document.write("audioUrl:" + audioUrl);});

这是在页面初始化时,通过扩展参数extras传值;另外还有页面已创建,通过自定义事件传值,参考mui官网中自定义事件的介绍,这里先不讲得太多,后面会专门花时间详细讲解相关细节。

当我们写到这里,发现这篇依然是长长的一篇干货,很多内容摘自文档,主要是为了新手可以详细去了解整个流程。其实还有很多没有写出来,限于篇幅还是后面再写吧!由于代码在文章中写得很详细,工程代码先不给出来,最后整个系列写完了再放出来吧!

随便聊聊

这段时间在技术上花得时间确实太多,刚刚和女朋友在图书馆学习,她和我开个玩笑,我在忙着做作业因为不喜欢被打扰,然后就觉得很烦躁,然后就聊着聊着她说和我分手,我不知道她是不是认真的,只是觉得空空的,自从走上代码这条路,我已经失去太多东西,我不想失去女朋友,毕竟谈了三年,我是真的爱她,写完这个就去找她道歉吧!还有要向环头道歉,昨天可能说话有点直接,不小心伤到他了,后来想想真的可能是我太较真,他只是想玩玩程序,我何必那种执着呢?如果环头看到这篇博客,希望你可以原谅哥,我只是不想让你走弯路,或许每个都应该自己去把握自己的人生,我们不必去干涉。

写文章不容易,也许写这些代码就几分钟的事,写一篇大家好接受的文章或许需要几天的酝酿,然后加上几天的码字,累并快乐着。如果文章对您有帮助请我喝杯咖啡吧!

关键字:html5plus, mui, dcloud, hbuilder


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部