一、Ajax
1、Ajax 是什么
Ajax 是 Asynchronous JavaScript and XML(异步 JavaScript 和 XML)的简写
- Ajax 中的异步:可以异步地向服务器发送请求,在等待响应的过程中,不会阻塞当前页面,浏览器可以做自己的事情。直到成功获取响应后,浏览器才开始处理响应数据
- XML(可扩展标记语言)是前后端数据通信时传输数据的一种格式,XML 现在已经不怎么用了,现在比较常用的是 JSON
- Ajax 其实就是浏览器与服务器之间的一种异步通信方式
- 使用 Ajax 可以在不重新加载整个页面的情况下,对页面的某部分进行更新
2、搭建 Ajax 开发环境
Ajax 需要服务器环境,非服务器环境下,很多浏览器无法正常使用 Ajax
- Live Server
- windows phpStudy
- Mac MAMP
3、Ajax 的使用步骤
- 创建 xhr 对象
- 监听事件,处理响应
- 准备发送请求
- 发送请求
4、使用 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 === 304) {
console.log(xhr.responseText);
console.log(typeof xhr.responseText);
}
};
xhr.open('GET', url, true);
xhr.send(null);
5、Get请求
- 携带数据:GET 请求不能通过请求体携带数据,但可以通过请求头携带
const url = '[https://www.imooc.com/api/http/search/suggest?words=js&username=alex&age=18'](https://links.jianshu.com/go?to=https%3A%2F%2Fwww.imooc.com%2Fapi%2Fhttp%2Fsearch%2Fsuggest%3Fwords%3Djs%26username%3Dalex%26age%3D18%27);
- 数据编码
- 如果携带的数据是非英文字母的话,比如说汉字,就需要编码之后再发送给后端,不然会造成乱码问题
- 可以使用 encodeURIComponent() 编码
6、POST请求
- 携带数据:
- POST 请求主要通过请求体携带数据,同时也可以通过请求头携带
- 如果想发送数据,直接写在 send() 的参数位置,一般是字符串
- 不能直接传递对象,需要先将对象转换成字符串的形式
- 数据编码:
xhr.send(username=${encodeURIComponent('张三')}&age=18);
7、 JSON 是什么
Ajax 发送和接收数据的一种格式
8、为什么需要 JSON
JSON 有 3 种形式,每种形式的写法都和 JS 中的数据类型很像,可以很轻松的和 JS 中的数据类型互相转换
9、JSON 的 3 种形式
-
简单值形式
- JSON 的简单值形式就对应着 JS 中的基础数据类型: 数字、字符串、布尔值、null
- 注意事项
① JSON 中没有 undefined 值
② JSON 中的字符串必须使用双引号
③ JSON 中是不能注释的
-
对象形式
- JSON 的对象形式就对应着 JS 中的对象
- 注意事项
① JSON 中对象的属性名必须用双引号,属性值如果是字符串也必须用双引号
② JSON 中只要涉及到字符串,就必须使用双引号
③ 不支持 undefined
-
数组形式
- JSON 的数组形式就对应着 JS 中的数组: [1, "hi", null]
- 注意事项
① 数组中的字符串必须用双引号
② JSON 中只要涉及到字符串,就必须使用双引号
③ 不支持 undefined
10、JSON 的常用方法
-
JSON.parse()
: 可以将 JSON 格式的字符串解析成 JS 中的对应值,一定要是合法的 JSON 字符串,否则会报错 -
JSON.stringify()
:可以将 JS 的基本数据类型、对象或者数组转换成 JSON 格式的字符串
11、使用 JSON.parse() 和 JSON.stringify() 封装 localStorage
const storage = window.localStorage;
// 设置
const set = (key, value) => {
// {
// username: 'alex'
// }
storage.setItem(key, JSON.stringify(value));
};
// 获取
const get = key => {
// 'alex'
// {
// "username": "alex"
// }
return JSON.parse(storage.getItem(key));
};
// 删除
const remove = key => {
storage.removeItem(key);
};
// 清空
const clear = () => {
storage.clear();
};
export { set, get, remove, clear };
12、跨域是什么
- 向一个域发送请求,如果要请求的域和当前域是不同域,就叫跨域
- 不同域之间的请求,就是跨域请求
13、什么是不同域,什么是同域
协议、域名、端口号,任何一个不一样,就是不同域
与路径无关,路径一不一样无所谓
14、跨域请求为什么会被阻止
阻止跨域请求,其实是浏览器本身的一种安全策略--同源策略
其他客户端或者服务器都不存在跨域被阻止的问题
15、跨域解决方案
- CORS 跨域资源共享
- JSONP
优先使用 CORS 跨域资源共享,如果浏览器不支持 CORS 的话,再使用 JSONP
16、JSONP 的原理
- script 标签跨域不会被浏览器阻止
- JSONP 主要就是利用 script 标签,加载跨域文件
17、使用 JSONP 实现跨域
- 服务器端准备好 JSONP 接口
script.src = 'https://www.imooc.com/api/http/jsonp?callback=handleResponse'; document.body.appendChild(script); // 声明函数 const handleResponse = data => { console.log(data); };
18、XHR 的属性
-
responseType
和response
属性:文本形式的响应内容 IE6~9 不支持,IE10 开始支持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 === 304) { // 文本形式的响应内容 // responseText 只能在没有设置 responseType 或者 responseType = '' 或 'text' 的时候才能使用 // console.log('responseText:', xhr.responseText); // 可以用来替代 responseText console.log('response:', xhr.response); // console.log(JSON.parse(xhr.responseText)); } }; xhr.open('GET', url, true); // xhr.responseType = ''; // xhr.responseType = 'text'; xhr.responseType = 'json'; xhr.send(null);
-
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 === 304) { console.log(xhr.response); } }; xhr.open('GET', url, true); xhr.timeout = 10000; xhr.send(null);
-
withCredentials
属性 : 指定使用 Ajax 发送请求时是否携带 Cookie IE6~9 不支持,IE10 开始支持// 使用 Ajax 发送请求,默认情况下,同域时,会携带 Cookie;跨域时,不会 xhr.withCredentials = true; // 最终能否成功跨域携带 Cookie,还要看服务器同不同意 const url = 'https://www.imooc.com/api/http/search/suggest?words=js'; // const url = './index.html'; const xhr = new XMLHttpRequest(); xhr.onreadystatechange = () => { if (xhr.readyState != 4) return; if ((xhr.status >= 200 && xhr.status < 300) || xhr.status === 304) { console.log(xhr.response); } }; xhr.open('GET', url, true); xhr.withCredentials = true; xhr.send(null);
19、XHR 的方法
-
abort()
终止当前请求, 一般配合 abort 事件一起使用const xhr = new XMLHttpRequest(); xhr.onreadystatechange = () => { if (xhr.readyState != 4) return; if ((xhr.status >= 200 && xhr.status < 300) || xhr.status === 304) { console.log(xhr.response); } }; xhr.open('GET', url, true); xhr.send(null); xhr.abort();
-
setRequestHeader()
setRequestHeader// xhr.setRequestHeader(头部字段的名称, 头部字段的值); const url = 'https://www.imooc.com/api/http/json/search/suggest?words=js'; const xhr = new XMLHttpRequest(); xhr.onreadystatechange = () => { if (xhr.readyState != 4) return; if ((xhr.status >= 200 && xhr.status < 300) || xhr.status === 304) { console.log(xhr.response); } }; xhr.open('POST', url, true); // 请求头中的 Content-Type 字段用来告诉服务器,浏览器发送的数据是什么格式的 // xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded'); xhr.setRequestHeader('Content-Type', 'application/json'); // xhr.send(null); // xhr.send('username=alex&age=18'); xhr.send( JSON.stringify({ username: 'alex' }) );
20、XHR 的事件
-
load
事件:响应数据可用时触发, IE6~8 不支持 load 事件const url = 'https://www.imooc.com/api/http/search/suggest?words=js'; const xhr = new XMLHttpRequest(); xhr.onload = () => { if ((xhr.status >= 200 && xhr.status < 300) || xhr.status === 304) { console.log(xhr.response); } }; // xhr.addEventListener( // 'load', // () => { // if ((xhr.status >= 200 && xhr.status < 300) || xhr.status === 304) { // console.log(xhr.response); // } // }, // false // ); // xhr.open('GET', url, true); // xhr.send(null);
-
error
事件: 请求发生错误时触发、 IE10 开始支持const url = 'https://www.imooc.com/api/http/search/suggest?words=js'; 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 === 304) { console.log(xhr.response); } }, false ); // xhr.addEventListener( // 'error', // () => { // console.log('error'); // }, // false // ); xhr.open('GET', url, true); xhr.send(null);
-
abort
事件:调用 abort() 终止请求时触发, IE10 开始支持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 === 304) { console.log(xhr.response); } }, false ); // xhr.addEventListener( // 'abort', // () => { // console.log('abort'); // }, // false // ); xhr.open('GET', url, true); xhr.send(null); xhr.abort();
-
timeout
事件:请求超时后触发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 === 304) { console.log(xhr.response); } }, false ); xhr.addEventListener( 'timeout', () => { console.log('timeout'); }, false ); xhr.open('GET', url, true); xhr.timeout = 10; xhr.send(null);
21、axios
axios 是一个基于 Promise 的 HTTP 库,可以用在浏览器和 node.js 中,第三方 Ajax 库