Fork me on GitHub

AJAX基础

为什么要使用Ajax?

优点

  • 通过异步模式,提升了用户体验
  • 优化了浏览器之间的传输,减少了不必要的数据返回,减少了带宽的占用
  • Ajax引擎在客户端运行,承担了一部分本来由服务器承担的工资,从而减少了大用户量下的服务器负载

缺点

  • 不支持浏览器back按钮
  • 安全问题AJAX暴露了与服务器交互的细节
  • 对搜索引擎的支持比较弱

XMLHttpRequest对象

是一种支持异步请求的技术,它是Ajax的核心

XMLHttpRequest的作用

  • 可以向服务器提出请求并处理响应式,而不阻塞用户
  • 可以在页面加载以后进行页面的局部更新

如何使用Ajax?

  1. 创建XMLHttpRequest对象,也就是创建一个异步调用对象

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
    // 封装通用的Xhr对象,兼容各个版本
function createXHR() {
// 判断浏览器是否将XMLHttpRequest作为本地对象实现,针对IE7,firefox opera等
if (typeof XMLHttpRequest != "undefined") {
// 返回 XMLHttpRequest对象的实例
return new XMLHttpRequest();
} else if (typeof ActiveXObject != "undefined") {
// 将所有可能出现的 ActiveXObject版本放到一个数组中
var xhrArr = ['Microsoft.XMLHTTP',
'MSXML2.XMLHTTP.6.0',
'MSXML2.XMLHTTP.5.0',
'MSXML2.XMLHTTP.4.0',
'MSXML2.XMLHTTP.3.0',
'MSXML2.XMLHTTP.2.0']
// 需要遍历创建 XMLHttpRequest 对象
var len = xhrArr.length, xhr;
for (var i = 0; i < len; i++) {
try {
// 创建 XMLHttpRequest 对象
xhr = new ActiveXObject(xhrArr[i]);
// 退出,当前循环
break;
}
catch (ex) {
// 没有找到版本
}
}
// 找到了,返回 当前对象,并退出
return xhr;
}else {
// 都不支持的情况,自动抛出一个错误
throw new Error('No XHR object availabel.')
}
}

// 调用 函数,查看是否 找到版本
var xhr = createXHR();
console.log(xhr);


// >> XMLHttpRequest
// 打印除这个对象证明 :创建成功
  1. 创建一个新的HTTP请求,并指定该HTTP请求方法/URL

    语法:open( method , url , async )

    功能:创建HTTP请求,规定请求的类型, URL及是否异步处理请求

    参数说明:

    ​ method: 请求类型,GET 或 POST

    ​ url: 文件在服务器上的位置

    ​ async : true( 异步 ) 或 false ( 同步 )

    注意事项:

    • open 方法不会向服务器发送真正的请求,它相当于初始化请求并准备发送只能向同一个域中使用相同协议和端口的URL发送请求,否则因为安全原因报错。

    • URL参数是Open()方法中唯一必须要指定的参数,用来设置服务器上文件的地址,该文件可以是任何类型的文件,如.txt 和 .xml ,或者服务器脚本文件,如.asp 和 .php (在传回响应之前,能够在服务器上执行任务)

    • GET 与 POST 的区别

      与 POST 相比,GET 更简单,更快, 并且在大部分情况下都能用,然而在以下情况中,必须使用POST 请求:

      1. 无法使用缓存文件(更新服务器上的文件和数据库)
      2. 向服务器发送大量数据(POST没有数据量限制)
      3. 发送包含未知字符,大量数据 或用户输入时,POST比GET 更稳定也更可靠
    • 同步与异步的区别

      1. 同步: 提交请求 -> 等待服务器处理 -> 处理完毕返回,这个期间客户端浏览器不能做任何事
      2. 异步:请求通过事件触发 -> 服务器处理(这时浏览器依然可以做其他事件) -> 处理完毕
    • async 是一个布尔值,如果是异步通信方式(true),客户机就不等待服务器的响应;如果是同步方式(false),客户机就要等到服务器返回消息后才能去执行其他操作。

      1
      2
      // 2.创建请求
      xhr.open('get','./server/slider.json',true);
  1. 设置响应HTTP请求状态变化的函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// 3. 习惯把这一步,放到  创建请求上面👆

// 3. 响应XMLHTTPRequest对象 状态变化的函数
// onread-ystate-change = 准备 状态 改变 = 属性发生改变时触发
xhr.onreadystatechange = function(){

// 异步调用成功,响应内容解析完成,意味客户端可以调用
// 0 1 2 3 4 = 初始化 正在发送请求 执行完成 正在解析 异步解析成功
if (xhr.onreadystatechange === 4) {

// 调用成功了后判断: 当大于200,且小于300 ,则证明 我们的异步调用才是成功.
// 304 = 请求资源没有被修改,可以使用浏览器缓存。
if (xhr.status >= 200 && xhr.status < 300 || xhr.status === 304){

// 获得服务器返回的数据

}
}
};
  1. 发送HTTP请求

    如果发送请求

    语法:send(string)

    功能:将请求发送到服务器

    参数说明:string 仅用于post请求

    注意事项:仅在POST请求时可以传入参数,不需要则发送null ,在调用 send方法之后请求被发往服务器

    如何添加HTTP头

    如果需要像HTML表单那样 POST 数据,需要使用 setRequestHeader() 来添加HTTP头,然后再send() 方法中规定希望发送的数据

    语法: xmlhttp.setRequestHeader( header, value )

    使用:xmlhttp.setRequestHeader( “Content-type”,”applicatication/x-www-form-urlencoded” );

1
2
3
4
5
6
7
8
9
// 4.发送HTTP请求

// 没数据,发送请求
xhr.send(null);

// 有数据,发送请求
xhr.send({user:'huzhongqiang',age: 26, name: '胡肥肥' });
// 设置HTTP 头部请求
xhr.setRequestHeader( "Content-type","applicatication/x-www-form-urlencoded" );
  1. 获取异步调用返回的数据

在收到响应后响应数据会填充到XHR对象的属性,有四个相关属性会被填充:

  • responseText ———– 从服务器进程返回数据的字符串形式
  • responseXML ———— 从服务器进程返回的DOM 兼容的文档数据对象
  • status————————从服务器返回的数字代码,如404(未找到)和200(已就绪)
  • status Text —————–伴随状态码的字符串信息
1
2
// 获得服务器返回的数据
console.log(xhr.response )

什么是JSON ?

JSON全称是JavaScript对象表示法,它是一种数据交换的文本格式,而不是一种编程语言,用于读取结构化数据,2001年由Douglas C rockford 提出,目的是取代繁琐笨重的XML格式

JSON的语法可以表示以下三种类型的值:

简单值:

简单值使用与 JavaScript相同的语法,可以在JSON中表示字符串,数值,布尔值和null

字符串必须使用双引号表示,不能用单引号,数值必须以十进制表示,且不能用NaN和Infinity

说明:JSON不支持JavaScript中的特殊值 undefined

对象:

对象作为一种复杂数据类型,表示的是一组有序的键值对儿,而每个键值对儿中的可以是简单值,也可以是复杂数据类型的值

JSON 中对象的键名必须放在双引号里面,因为JSON 不是JavaScript语句,所以没有未尾的分号

说明:同一个对象中不应该出现俩个同名属性

数值:

数值也是一种复杂的数据类型,表示一组有序的值的列表,可以通过数值索引来访问其中的值

说明:数组或对象最后一个成员后面,不能加逗号

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
{
"code": 0, // 简单值
"slider": [
{
"linkUrl": "https://m.imooc.com/act/share",
"picUrl": "img/fm1.jpg"
},{
"linkUrl": "https://m.imooc.com/act/share",
"picUrl": "img/fm2.jpg"
},{
"linkUrl": "https://m.imooc.com/act/share",
"picUrl": "img/fm3.jpg"
},{
"linkUrl": "https://m.imooc.com/act/share",
"picUrl": "img/fm4.jpg"
},{
"linkUrl": "https://m.imooc.com/act/share",
"picUrl": "img/fm5.jpg"
},{
"linkUrl": "https://m.imooc.com/act/share",
"picUrl": "img/fm6.jpg"
}
]
}
  1. 使用JavaScript 和DOM 实现局部刷新

    JSON 对象的俩个方法:

    1
    2
    3
    parse()
    语法: JSON.parse()
    功能:用于将JSON字符串转化成对象
    1
    2
    3
    stringify()
    语法:JSON.stringify()
    功能:用于将一个值转为字符串,该字符串应该符号JSON格式并且可以被JSON.parse()方法还原
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    // 3. 响应XMLHTTPRequest对象 状态变化的函数
    // onread-ystate-change = 准备 状态 改变 = 属性发生改变时触发
    xhr.onreadystatechange = function () {
    // 异步调用成功,响应内容解析完成,意味客户端可以调用
    // 0 1 2 3 4 = 初始化 正在发送请求 执行完成 正在解析 异步解析成功
    if (xhr.onreadystatechange === 4) {
    // 调用成功了后判断: 当大于200,且小于300 ,则证明 我们的异步调用才是成功.
    // 304 = 请求资源没有被修改,可以使用浏览器缓存。
    if (xhr.status >= 200 && xhr.status < 300 || xhr.status === 304) {
    // 获得服务器返回的数据
    data = JSON.parse(xhr.responseText);
    // console.log(data.slider)

    // 6 渲染数据页面中,函数,在外面👇
    renderDataToDom();

    }
    }
    };


    // 渲染数据
    function renderDataToDom() {
    var img = data.slider, i,
    len = img.length, str = "",
    banner = document.getElementById("banner");
    // 遍历数据,拼接字符串
    for (i = 0; i < len; i++) {
    str += '<a href="' + img[i].linkUrl + '"><img src="' + img[i].picUrl + '"></a>'
    }
    // 渲染图片信息
    banner.innerHTML = str;
    }

jquery的ajax方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
// jquery的 $ajax()
$.ajax({
url: './server/slider.json', // 请求地址
type: 'post', // 请求方式
async: true, // 同步异步
dataType: 'json', // 数据格式
success: function (imgData) {// 请求成功的回调
console.log(imgData);
// 渲染数据函数
jQrenderDataToDom(imgData.slider);
}
});

// 渲染数据
function jQrenderDataToDom(data) {
console.log(data);
// 遍历数据
var str = '';
$.each(data,function (index,obj) {
// console.log(index);
// console.log(obj.linkUrl);
// 每次循环,在str 中 创建 a > img 标签
str += '<a href="' + obj.linkUrl + '"><img src="' + obj.picUrl + '"></a>'
});
// 每次循环后,追加到 banner_jq 标签中
$('#banner_jq').html(str);
}

什么是跨域?

所谓的同源是指:域名,协议,端口均相同

跨域是指从一个域名的网页去请求到另外一个域名的资源,严格一点的定义是: 只要协议有任何一个不同,就被当做跨域

如何解决跨域

  • 跨域资源共享 (CORS)
  • 使用JSONP (常用)
  • 修改docment.domain
  • 使用window.name

什么是JSONP

JSONP 是 JSON with Padding (填充式 json)的简写,是应用JSON 的一个新方法,也是一种跨域解决方案

JSONP 的组成

JSONP 由俩部分组成: 回调函数 和数据,

​ 回调函数是当响应 到来时 应该在页面中调用的函数,

​ 而数据就是传入回调函数中的JSON 数据

JSONP 的原理

直接用XMLHttpRequest 请求不同域上的数据时,是不可以的。但是,在页面上引入不用域上的JS脚本文件却是可以的,jsonp 正是利用这个特性来实现的