05-接口化开发,art-template,隐藏域,timeout,FormData,upload,onprogress,jsonp原理,XHR2.0,CORS

接口化开发

请求地址即所谓的接口,通常所说的接口化开发,其实是指一个接口对应一个功能, 并且严格约束了请求参数响应结果 的格式,这样前后端在开发过程中,可以减少不必要的讨论, 从而并行开发,可以极大的提升开发效率,另外一个好处,当网站进行改版后,服务端接口进行调整时,并不影响到前端的功能。

注册接口

表单序列化

jquery提供了一个serialize()方法序列化表单,说白就是将表单中带有name属性的所有参数拼成一个格式为name=value&name1=value1这样的字符串。方便我们获取表单的数据。

1
2
3
4
// serialize将表单参数序列化成一个字符串。必须指定name属性
// name=hucc&pass=123456&repass=123456&mobile=18511249258&code=1234
$('form').serialize();

jquery的ajax方法,data参数能够直接识别表单序列化的数据data:$('form').serialize()

1
2
3
4
5
6
7
8
$.post({
url:"register.php",
data:$('form').serialize(),
dataType:'json',
success:function (info) {
console.log(info);
}
});

模板引擎

是为了使用户界面与业务数据(内容)分离而产生的,它可以生成特定格式的文档,用于网站的模板引擎就会生成一个标准的HTML文档。

使用模板引擎的好处

通过ajax获取到数据后,需要把数据渲染到页面,大量的拼接字符串只适用于结构简单的页面,但是如果页面结构很复杂,使用拼串的话代码可阅读性非常的差,而且非常容易出错,后期代码维护也是相当的麻烦。

【演示:使用拼串进行渲染的缺点.html】

作用:代替前面渲染数据是拼接字符串操作

实际工作渲染数据使用的模板引擎

常见的模板引擎

BaiduTemplate:http://tangram.baidu.com/BaiduTemplate/
velocity.js:https://github.com/shepherdwind/velocity.js/
ArtTemplate:https://github.com/aui/artTemplate

artTemplate的使用

github地址

中文api地址

artTemplate入门

1.引入模板引擎的js文件

1
<script src="template-web.js"></script>

2.准备模板

1
2
3
4
5
6
7
8
9
<!--
指定了type为text/template后,浏览器就无法解析了。
-->
<script type="text/template" id="tmp">
<p>姓名:{{ username }}</p>
<p>年龄:{{ age }}</p>
<p>技能:{{ skill }}</p>
<p>描述:{{desc }}</p>
</script>

3.准备数据

1
2
3
4
5
6
7
// 模拟数据,数据是后台获取的,可以随时变化
var json = {
userName:"hoho",
age:18,
skill:"code",
desc:"haha"
}

4.将模板与数据进行绑定

1
2
3
4
// 第一个参数:模板的id
// 第二个参数:数据(对象格式)
// 返回值:根据模板生成的字符串。
var html = template("myTmp", json);

5.将数据显示到页面

1
2
var div = document.querySelector("div");
div.innerHTML = html;

注意:传递给模板引擎的数据必须是对象

artTemplate语法

if语法

1
2
3
4
5
{{if gender='男'}}
<div class="man">
{{else}}
<div class="woman">
{{/if}}

each语法

1
2
3
4
5
6
7
8
9
10
11
12
<!--
1. {{each data}} 可以通过$value 和 $index获取值和下标
2. {{each data v i}} 自己指定值为v,下标为i
-->
{{each data v i}}
<li>
<a href="{{v.url}}">
<img src="{{v.src}}" alt="">
<p>{{v.content}}</p>
</a>
</li>
{{/each}}
1
2
// 如果返回的数据是个数组,必须使用对象进行包裹,因为在{{}}中只写书写对象的属性。
var html = template("navTmp", {data:info});

同源与跨域

同源

不同源 则跨域

同源策略的基本概念

1995年,同源政策由 Netscape 公司引入浏览器。目前,所有浏览器都实行这个政策。
同源策略:最初,它的含义是指,A网页设置的 Cookie,B网页不能打开,除非这两个网页”同源”。现在浏览器的所谓”同源”指的是”三个相同”:

  • 协议相同
  • 域名相同
  • 端口相同

举例来说,http://www.example.com/dir/page.html这个网址,协议是http://,域名是www.example.com,端口是80(默认端口可以省略)。它的同源情况如下。

1
2
3
4
// http://www.example.com/dir2/other.html:同源
// http://example.com/dir/other.html:不同源(域名不同)
// http://v2.www.example.com/dir/other.html:不同源(域名不同)
// http://www.example.com:81/dir/other.html:不同源(端口不同)

同源策略的目的

同源政策的目的,是为了保证用户信息的安全,防止恶意的网站窃取数据。

同源策略的限制范围

随着互联网的发展,“同源策略”越来越严格,目前,如果非同源,以下三种行为都将收到限制。

1
2
3
// 1. Cookie、LocalStorage 无法读取。
// 2. DOM 无法获得。
// 3. AJAX 请求不能发送。

虽然这些限制是很有必要的,但是也给日常开发带来不好的影响。实际开发过程中,往往都会把服务器端架设到一台甚至是一个集群的服务器中,把客户端页面放到另外一个单独的服务器。那么这时候就会出现不同源的情况,如果我们知道两个网站都是安全的话,我们是希望两个不同源的网站之间可以相互请求数据的。这就需要使用到跨域

跨域

jsonp

JSONP(JSON with Padding)、可用于解决主流浏览器的跨域数据访问的问题。

原理:服务端返回一个预先定义好的javascript函数的调用,并且将服务器的数据以该函数参数的形式传递过来,这个方法需要前后端配合。

script 标签是不受同源策略的限制的,它可以载入任意地方的 JavaScript 文件,而并不要求同源。类似的还有imglink标签

1
2
3
4
<!--不受同源策略的标签-->
<img src="http://www.api.com/1.jpg" alt="">
<link rel="stylesheet" href="http://www.api.com/1.css">
<script src="http://www.api.com/1.js"></script>

jquery对于jsonp的封装

1
2
3
4
5
6
7
8
9
10
11
12
13
// 跟普通的get请求没有任何的区别,只需要把dataType固定成jsonp即可。
$.ajax({
type:"get",
url:"http://www.api.com/testjs.php",
dataType:"jsonp",
data:{
uname:"hucc",
upass:"123456"
},
success:function (info) {
console.log(info);
}
});

http://lbsyun.baidu.com/index.php?title=car/api/weather

天气查询api地址

图灵机器人:http://www.tuling123.com/

XMLHttpRequest 2.0

XMLHttpRequest是一个javascript内置对象,使得Javascript可以进行异步的HTTP通信。2008年2月,就提出了XMLHttpRequest Level 2 草案。

老版本的XMLHttpRequest的缺点:

1
2
3
// 1. 仅支持传输文本数据,无法传说二进制文件,比如图片视频等。
// 2. 传输数据时,没有进度信息,只能提示完成与否。
// 3. 受到了"同源策略"的限制

新版本的功能:

1
2
3
// 1. 可以设置timeout 超时时间
// 2. 可以使用formData对象管理表单数据
// 3. 可以获取数据传输的进度信息

注意:现在使用new XMLHttpRequest创建的对象就是2.0对象了,只要学习一些2.0的新特性即可。

timeout超时事件

1
2
3
4
xhr.timeout = 3000;// 设置超时时间
xhr.ontimeout = function(){
alert("请求超时");
}

formData管理表单数据

formData对象类似于jquery的serialize方法,用于管理表单数据

1
2
3
4
5
// 使用特点: 
// 1. 实例化一个formData对象, new formData(form); form就是表单元素
// 4. formData对象可以直接作为 xhr.send(formData)的参数。注意此时数据是以二进制的形式进行传输。
// 5. formData有一个append方法,可以添加参数。formData.append("id", "1111");
// 6. 这种方式只能以post形式传递,不需要设置请求头,浏览器会自动为我们设置一个合适的请求头。

代码示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
// 1. 使用formData必须发送post请求
xhr.open("post", "02-formData.php");

// 2. 获取表单元素
var form = document.querySelector("#myForm");
// 3. 创建form对象,可以直接作为send的参数。
var formData = new FormData(form);

// 4. formData可以使用append方法添加参数
formData.append("id", "1111");

// 5. 发送,不需要指定请求头,浏览器会自动选择合适的请求头
xhr.send(formData);

文件上传

以前,文件上传需要借助表单进行上传,但是表单上传是同步的,也就是说文件上传时,页面需要提交和刷新,用户体验不好,xhr2.0中的formData对象支持文件的异步上传。

1
2
3
4
5
var formData = new FormData();
// 获取上传的文件,传递到后端
var file = document.getElementById("file").files[0];
formData.append("file", file);
xhr.send(formData);

显示文件进度信息

xhr2.0还支持获取上传文件的进度信息,因此我们可以根据进度信息可以实时的显示文件的上传进度。

  1. 需要注册 xhr.upload.onprogress = function(e){} 事件,用于监听文件上传的进度.注意:需要在send之前注册。
  2. 上传的进度信息会存储事件对象e中
  3. e.loaded表示已上传的大小 e.total表示整个文件的大小

代码参考:

1
2
3
4
5
6
7
xhr.upload.onprogress = function (e) {

inner.style.width = (e.loaded/e.total*100).toFixed(2)+"%";
span.innerHTML = (e.loaded/e.total*100).toFixed(2)+"%";
}

xhr.send(formData);

如果上传文件超过8M,php会报错,需要进行设置,允许php上传大文件。

跨域资源共享(CORS)

CORS的使用

新版本的XMLHttpRequest对象,可以向不同域名的服务器发出HTTP请求。这叫做“跨域资源共享”(Cross-origin resource sharing,简称CORS)。

跨域资源共享(CORS)的前提

  • 浏览器支持这个功能
  • 服务器必须允许这种跨域。

服务器允许跨域的代码:

1
2
3
4
// 允许所有的域名访问这个接口
header("Access-Control-Allow-Origin:*");
// 允许www.study.com这个域名访问这个接口
header("Access-Control-Allow-Origin:http://www.study.com");

CORS的具体流程

  1. 浏览器会根据同源策略 查看是否是跨域请求,如果同源,直接发送ajax请求。
  2. 如果非同源,说明是跨域请求,浏览器会自动发送一条请求(预检请求),并不会携带数据,服务器接受到请求之后,会返回请求头信息,浏览器查看返回的响应头信息中是否设置了header('Access-Control-Allow-Origin:请求源域名或者*');
  3. 如果没有设置,说明服务器不允许使用cors跨域,那么浏览器不会发送真正的ajax请求。
  4. 如果返回的响应头中设置了header('Access-Control-Allow-Origin:请求源域名或者*');,浏览器会跟请求头中的Origin: http://www.study.com进行对比,如果满足要求,则发送真正的ajax请求,否则不发送。
  5. 结论:跨域行为是浏览器行为,是浏览器阻止了ajax行为。服务器与服务器之间是不存在跨域的问题的,所以也可以使用服务器代理来发送ajax。