Ajax

初识 Ajax

  1. Ajax 是什么
    Ajax 是 Asynchronous JavaScript and XML(异步 JavaScript 和 XML)的简写

Ajax 中的异步:可以异步地向服务器发送请求,在等待响应的过程中,不会阻塞当前页面,浏览器可以做自己的事情。直到成功获取响应后,浏览器才开始处理响应数据

XML(可扩展标记语言)是前后端数据通信时传输数据的一种格式

XML 现在已经不怎么用了,现在比较常用的是 JSON

Ajax 其实就是浏览器与服务器之间的一种异步通信方式

使用 Ajax 可以在不重新加载整个页面的情况下,对页面的某部分进行更新

Ajax 的基本用法

  1. XMLHttpRequest
    Ajax 想要实现浏览器与服务器之间的异步通信,需要依靠 XMLHttpRequest,它是一个构造函数

不论是 XMLHttpRequest,还是 Ajax,都没有和具体的某种数据格式绑定

  1. Ajax 的使用步骤
    2.1 创建 xhr 对象
const xhr = new XMLHttpRequest();

2.4 监听事件,处理响应
当获取到响应后,会触发 xhr 对象的 readystatechange 事件,可以在该事件中对响应进行处理

xhr.addEventListener('readystatechange', () => {}, false);

xhr.onreadystatechange = () => {
	if (xhr.readyState !== 4) return;
	// xhr.status: HTTP 200 404
	// xhr.statusText: HTTP 状态说明 OK Not Found
	if ((xhr.status >= 200 && xhr.status < 300) || xhr.status === 304) {
		console.log(xhr.responseText);	// 返回的数据
	}
}

readystatechange 事件也可以配合 addEventListener 使用,不过要注意,IE6~8不支持 addEventListener
为了兼容性,readystatechange 中不使用 this,而是直接使用 xhr
由于兼容性的问题,最好放在 open 之前

readystatechange 事件监听 readyState 这个状态的变化
它的值从 0~4,一共 5 个状态

0: 未初始化。尚未调用 open()
1: 启动。已经调用 open(),但尚未调用 send()
2: 发送。已经调用 send(),但尚未接收到响应
3: 接收。已经接收到部分响应数据
4: 完成。已经接收到全部响应数据,而且已经可以在浏览器中使用了

2.2 准备发送请求
调用 open 并不会真正发送请求,而只是做好发送请求前的准备工作

xhr.open(
	'HTTP 方法 GET、POST、PUT、DELETE',
	'地址 URL https://www.imooc.com/api/http/search/suggest?words=js ./index.html ./index.xml ./index.txt',
	'是否使用异步方式 true 是,只用 true 方式'
);

2.3 发送请求
调用 send() 正式发送请求

send() 的参数是通过请求体携带的数据

xhr.send(null);		// GET 方法不传送请求体,传 null 是为了兼容性的问题
  1. 使用 Ajax 完成前后端通信
const url = 'https://www.imooc.com/api/http/search/suggest?words=js';

const xhr = new XMLHttpRequest();

xhr.onreadystatechange = () => {
  if (xhr.readyState !== 4) return;
  if ((xhr.status >= 200 && xhr.status < 300) || xhr.status === 403) {
    console.log(xhr.responseText);
  }
}

xhr.open('GET', url, true);
xhr.send(null);

GET 请求

  1. 携带数据
    GET 请求不能通过请求体携带数据,但是可以通过请求头携带
const url = 'https://www.imooc.com/api/http/search/suggest?words=js&name=zs&age=18';

GET 请求时,send() 中写入数据不会报错,但不会发送数据

  1. 数据编码
    如果携带的数据是非英文字母的话,比如说汉字,就需要编码之后再发送给后端,不然会造成乱码问题,可以使用 encodeURIComponent() 编码
const url = `https://www.imooc.com/api/http/search/suggest?words=${encodeURIComponent('前端')}`;

POST 请求

  1. 携带数据
    POST 请求主要通过请求体携带数据,同时也可以通过请求头携带
    如果想发送数据,直接写在 send() 的参数位置,一般是字符串

不能直接传递对象,需要先将对象转换成字符串的形式

// 其中一种数据传输方式
xhr.send('username=zs&age=18');
  1. 数据编码
xhr.send(`username=${encodeURIComponent('张三')}&age=18`);

初识 JSON

  1. JSON 是什么
    Ajax 发送和接收数据的一种格式
    XML
    username=zs&age=18
    JSON

JSON 全称是 JavaScript Object Notation

  1. 为什么需要 JSON
    JSON 有 3 种形式,每种形式的写法都和 JS 中的数据类型很像,可以很轻松的和 JS 中的数据类型互相转换

JSON 的 3 种形式

  1. 简单值形式
    .json 文件
    JSON 的简单值形式就对应着 JS 中的基础数据类型
    数字、字符串、布尔值、null
5
"str"
true
null

注意事项
(1) JSON 中没有 undefined
(2) JSON 中的字符串必须使用双引号
(3) JSON 中是不能注释的

  1. 对象形式
    JSON 的对象形式就对应着 JS 中的对象
    注意事项
    JSON 中对象的属性名必须用双引号,属性值如果是字符串也必须用双引号
    JSON 中只要涉及到字符串,就必须使用双引号
    不支持 undefined
{
	"username": "张明明",
	"age": 18,
	"hobby": ["足球", "篮球"],
	"family": {
		"father": "张三",
		"mother": "李四"
	}
}
  1. 数组形式
    JSON 的数组形式就对应着 JS 中的数组
[1, "hi", null]

注意事项
数组中的字符串必须用双引号
JSON 中只要涉及到字符串,就必须使用双引号
不支持 undefined

JSON 的常用方法

  1. JSON.parse()
    JSON.parse() 可以将 JSON 格式的字符串解析成 JS 中的对应值
    一定要是合法的 JSON 字符串,否则会报错
console.log(JSON.parse(xhr.responseText));
  1. JSON.stringify()
    JSON.stringify() 可以将 JS 的基本数据类型、对象或者数组转换成 JSON 格式的字符串
xhr.send(JSON.stringify({
	username: 'zs',
	age: 18
}));
  1. 使用 JSON.parse() 和 JSON.stringify() 封装 localStorage

初识跨域

  1. 跨域是什么
    向一个域发送请求,如果要请求的域和当前域是不同域,就叫跨域
    不同域之间的请求,就是跨域请求
    不同域,跨域,被浏览器阻止

  2. 什么是不同域,什么是同域
    协议、域名、端口号,任何一个不一样,就是不同域
    与路径无关,路径一不一样无所谓

  3. 跨域请求为什么会被阻止
    阻止跨域请求,其实是浏览器本身的一种安全策略–同源策略
    其他客户端或者服务器都不存在跨域被阻止的问题

  4. 跨域解决方案
    (1) CORS 跨域资源共享
    (2) JSONP

优先使用 CORS 跨域组员共享,如果浏览器不支持 CORS 的话,再使用 JSONP

CORS 跨域资源共享

  1. CORS 是什么
    Access-Control-Allow-Origin: *
    在响应头部加上该属性,表明允许所有的域名来跨域请求它,* 是通配符,没有任何限制

只允许指定域名的跨域请求
Access-Control-Allow-Origin: http://127.0.0.1:5500

  1. 使用 CORS 跨域的过程
    (1) 浏览器发送请求
    (2) 后端在响应头中添加 Access-Control-Allow-Origin 头信息
    (3) 浏览器接收到响应
    (4) 如果是同域下的请求,浏览器不会额外做什么,这次前后端通信就圆满完成了
    (5) 如果是跨域请求,浏览器会从响应头中查找是否允许跨域访问
    (6) 如果允许跨域,通信圆满完成
    (7) 如果没找到或不包含想要跨域的域名,就丢弃响应结果

  2. CORS 的兼容性
    IE 10 及以上版本的浏览器可以正常使用 CORS

JSONP

  1. JSONP 的原理
    script 标签跨域不会被浏览器阻止
    JSONP 主要就是利用 script 标签,加载跨域文件

  2. 使用 JSONP 实现跨域
    服务器端准备好 JSONP 接口
    手动加载 JSONP 接口或动态加载 JSONP 接口

const script = document.createElement('script');
script.src = 'http://www.imooc.com/api/http/jsonp?callback=handleResponse';
document.body.appendChild(script);
// 声明函数
const handleResponse = data => {
	console.log(data);
}

XHR 的属性

  1. responseType 和 response 属性
    文本形式的响应内容
    responseText 只能在没有设置 responseType 或者 responseType = ‘’ 或者 ‘text’ 的时候才能使用
    response 可以替代 responseText,前提是没有兼容性问题
    response 和 responseType IE 6~9 不支持,IE 10 开始支持
const url = 'https://www.imooc.com/api/http/search/suggest?words=js';

const xhr = new XMLHttpRequest();

xhr.onreadystatechange = () => {
  if (xhr.readyState !== 4) return;
  if ((xhr.status >= 200 && xhr.status < 300) || xhr.status === 403) {
  	// response
    console.log(xhr.response);
  }
}

xhr.open('GET', url, true);
// responseType
// xhr.responseType = '';
// xhr.responseType = 'text';
xhr.responseType = 'json';
xhr.send(null);
  1. timeout 属性
    设置请求的超时事件(单位 ms)
    IE6~7 不支持,IE8 开始支持
const url = 'https://www.imooc.com/api/http/search/suggest?words=js';

const xhr = new XMLHttpRequest();

xhr.onreadystatechange = () => {
  if (xhr.readyState !== 4) return;
  if ((xhr.status >= 200 && xhr.status < 300) || xhr.status === 403) {
    console.log(xhr.response);
  }
}

xhr.open('GET', url, true);

// timeout
xhr.timeout = 10000;

xhr.send(null);
  1. withCredentials 属性
    指定使用 Ajax 发送请求时是否携带 Cookie

使用 Ajax 发送请求,默认情况下,同域时,会携带 Cookie;跨域时,不会
xhr.withCredentials = true;

最终能否成功跨域携带 Cookie,还要看服务器同不同意

IE6~9 不支持,IE 10 开始支持

XHR 的方法

  1. abort()
    终止发送请求

  2. setRequestHeader()
    可以设置请求头信息
    xhr.setRequestHeader(头部字段的名称,头部字段的值);

...
xhr.open('POST', url, true);

// xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
xhr.setRequestHeader('Content-Type', 'application/json');

xhr.send(JSON.stringify({
	username: 'zs'
}));
...

XHR 的事件

  1. load 事件
    响应数据可用时触发
    IE6~8 不支持 load 事件
const url = 'https://www.imooc.com/api/http/search/suggest?words=js';

const xhr = new XMLHttpRequest();

xhr.addEventListener('load', () => {
	if ((xhr.status >= 200 && xhr.status < 300) || xhr.status === 403) {
		console.log(xhr.response);
  	}
})

xhr.open('GET', url, true);
xhr.send(null);
  1. error 事件
    请求发生错误时触发
    IE 10 开始支持
const url = 'https://www.iimooc.com/api/http/search/suggest?words=js';

const xhr = new XMLHttpRequest();

xhr.addEventListener('load', () => {
	if ((xhr.status >= 200 && xhr.status < 300) || xhr.status === 403) {
		console.log(xhr.response);
  	}
});
xhr.addEventListener('error', () => {
	console.log('error');
});
xhr.open('GET', url, true);
xhr.send(null);
  1. abort 事件
    调用 abort() 终止请求时触发
    IE10 开始支持
const url = 'https://www.iimooc.com/api/http/search/suggest?words=js';

const xhr = new XMLHttpRequest();

xhr.addEventListener('load', () => {
	if ((xhr.status >= 200 && xhr.status < 300) || xhr.status === 403) {
		console.log(xhr.response);
  	}
});
xhr.addEventListener('abort', () => {
	console.log('abort');
});
xhr.open('GET', url, true);
xhr.send(null);
xhr.abort();
  1. timout 事件
    请求超时后触发
    IE 8 开始支持
const url = 'https://www.iimooc.com/api/http/search/suggest?words=js';

const xhr = new XMLHttpRequest();

xhr.addEventListener('load', () => {
	if ((xhr.status >= 200 && xhr.status < 300) || xhr.status === 403) {
		console.log(xhr.response);
  	}
});
xhr.addEventListener('timeout', () => {
	console.log('timeout');
});
xhr.open('GET', url, true);
xhr.timeout = 10000;
xhr.send(null);
xhr.abort();

FormData

  1. FormData 的基本用法
    通过 HTML 表单元素创建 FormData 对象
const fd = new FormData(表单元素);
xhr.send(fd);

通过 append() 方法添加数据

// 也可以步传入表单元素
const fd = new FormData();
fd.append('age', 18);
fd.append('sex', 'male');

IE 10 及以上可以支持

axios

  1. axios 是什么
    axios 是一个基于 Promise 的 HTTP 库,可以用在浏览器和 node.js 中
    第三方 Ajax 库

  2. axios 的基本用法
    引入 axios
    根据 http://www.axios-js.com/zh-cn/docs/ 文档中的说明进行引入

const url = 'https://www.imooc.com/api/http/json/search/suggest?words=js';
axios(url, /* 配置信息 */{
	method: 'post',
	/* 请求时的头信息 */
	headers: {
		'Content-Type': 'application/x-www-form-urlencoded'
	},
	/* 通过请求头携带的数据 */
	params: {
		username: 'alex'
	}
	/* 通过请求体携带的数据 */
	data: 'sex=male&age=18',
	// timeout: 10
	// withCredentials: true
})
.then(response => {
	console.log(response);
})
.catch(err => {
	console.log(err);
});

如果 data 中传入的为对象,那么 Content-Type 就为 application/json

axios.get(url, /* 配置信息 */{
	params: {
		username: 'zs'
	}
})
.then(response => {
	console.log(response);
})

请求中会根据请求体的数据自动添加 Content-Type

axios.post(url, /* 请求体中携带的数据 */{
	username: 'zs'
})
.then(response => {
	console.log(response);
})
.catch(err => {
	console.log(err);
});

创建 axios 实例

import axios from 'axios'
const instance = axios.create({
	baseURL: 'https://www.fastmock.site/mock/ae8e9031947a302fed5f92425995aa19/jd',
	timeout: 10000
})
const get = (url, param={}) => {
	return new Promise((resolve, reject) => {
		instance.get(url, { param })
			.then(response => {
				resolve(response.data)
			})
			.catch(err => {
				reject(err)
			})
	})
}
const post = (url, data = {}) => {
	return new Promise((resolve, reject) => {
		instance.post(url, data, {
			headers: {
				'content-type': 'application/json'
			}
		})
		.then(response => {
			resolve(response.data)
		})
		.catch(err => {
			reject(err);
		})
	})
}

Fetch

  1. Fetch 是什么
    Fetch 也是前后端通信的一种方式
    Fetch 是 Ajax (XMLHttpRequest) 的一种替代方案,它是基于 Promise 的
    Ajax 的兼容性比 Fetch 好
    Fetch 没有 abort timeout

  2. Fetch 的基本用法
    body: ReadableStream // fetch 提供一种方式读取其中的数据,body只能读一次,读过之后就不让再读了
    bodyUsed: false // 读过一次就变成 true 了,就不能再读了
    headers: Headers {}
    ok: true // 如果为 true ,数据就是可用的,不用再管状态码了
    redirected: false
    status: 200 // 状态码
    statusText: “OK” // 状态码的说明
    type: “cors”
    url: “https://www.imooc.com/api/http/search/suggest?words=js”
    __proto__: Response

  3. method, body, headers

fetch(url, /* 配置信息 */ {
	method: 'post',
	body: 'usename=zs&age=18',
	// body: JSON.stringify({username: 'zs'}),
	headers: {
		'Content-Type': 'application/x-www-form-urlencoded'
	}
	// headers: {
	//    'Content-Type': 'application/json'
	//}
})
.then(response => {
	if (response.ok) {
		return response.json();	// 读出数据 会返回 Promise 对象,用 then 获取
		// return response.text(); 	// 如果返回的不是 json 格式
	} else {
		throw new Error(`HTTP CODE 异常:${response.status}`);
	}
})
.then(data => {
	console.log(data);
})
// FormData 不需要传 Content-Type
const fd = new FormData();
fd.append('username', 'zs');
fetch(url, /* 配置信息 */ {
	method: 'post',
	body: fd
})
.then(response => {
	if (response.ok) {
		return response.json();	// 读出数据 会返回 Promise 对象,用 then 获取
		// return response.text(); 	// 如果返回的不是 json 格式
	} else {
		throw new Error(`HTTP CODE 异常:${response.status}`);
	}
})
.then(data => {
	console.log(data);
})
  1. mode
fetch(url, /* 配置信息 */ {
	method: 'post',
	body: 'usename=zs&age=18',
	headers: {
		'Content-Type': 'application/x-www-form-urlencoded'
	},
	mode: 'cors';  // 跨域资源共享,默认值就是 cors
})
...
  1. credentials 跨域是否携带 Cookie
fetch(url, /* 配置信息 */ {
	method: 'post',
	body: 'usename=zs&age=18',
	headers: {
		'Content-Type': 'application/x-www-form-urlencoded'
	},
	credentials: 'include'
})
...
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值