• 首页 首页 icon
  • 工具库 工具库 icon
    • IP查询 IP查询 icon
  • 内容库 内容库 icon
    • 快讯库 快讯库 icon
    • 精品库 精品库 icon
    • 问答库 问答库 icon
  • 更多 更多 icon
    • 服务条款 服务条款 icon

javascript的ajax

武飞扬头像
知勤者笔记
帮助1

学什么

Ajax基础
JSON
跨域
XHR对象
Ajax进阶
Ajax应用
Ajax扩展

Ajax基础

初识 Ajax
Ajax的基本用法
GET请求
POST请求

JSON

初识JSON
JSON的3种形式
JSON的常用方法

跨域

初识跨域
CORS跨域资源共享
JSONP

XHR 对象

XHR的属性
XHR的方法
XHR的事件

Ajax进阶

FormData
封装Ajax
使用Promise改造封装好的Ajax

Ajax应用

搜索提示
二级菜单
多个Ajax请求的并发执行

Ajax扩展

axios
Fetch

1.初识ajax

Ajax是什么
搭建Ajax开发环境

1.Ajax 是什么

Ajax 是 Asynchronous JavaScript and XML( 异步 JavaScript 和 XML)的简写
Ajax 中的异步:可以异步地向服务器发送请求,在等待响应的过程中,不会阻塞当前页面,浏览器可以做自己的事情。直到成功获取响应后,浏览器才开始处理响应数据
XML(可扩展标记语言)是前后端数据通信时传输数据的一种格式
  1.  
    xml标记语言
  2.  
    <person>
  3.  
    <name>张三</name>
  4.  
    <age>18</age>
  5.  
    <sex></sex>
  6.  
    </person>
  7.  
    <person>
  8.  
    <name>李四</name>
  9.  
    <age>28</age>
  10.  
    <sex></sex>
  11.  
    </person>
XML 现在已经不怎么用了,现在比较 常用的是 JSON
Ajax 其实就是浏览器与服务器之间的一种异步通信方式
使用 Ajax 可以在不重新加载整个页面的情况下,对页面的某部分进行更新

比如

① B站注册检测
② B站搜索提示
学新通
学新通

2.搭建 Ajax 开发环境

Ajax 需要服务器环境,非服务器环境下,很多浏览器无法正常使用 Ajax
windows phpStudy
Mac MAMP
学新通

2.Ajax的基本用法

  • XMLHttpRequest

  • Ajax的使用步骤

  • 使用Ajax完成前后端通信

1.XMLHttpRequest

  1.  
    console.log(Ajax); ×
  2.  
    // Ajax 想要实现浏览器与服务器之间的异步通信,需要依靠 XMLHttpRequest,它是一个构造函数
  3.  
    // 不论是 XMLHttpRequest,还是 Ajax,都没有和具体的某种数据格式绑定

2.Ajax 的使用步骤

2.1.创建 xhr 对象
const xhr = new XMLHttpRequest();
2.2.监听事件,处理响应
当获取到响应后,会触发 xhr 对象的 readystatechange 事件,可以在该事件中对响应进行处理
  1.  
    xhr.addEventListener('readystatechange', () => {}, fasle);
  2.  
    //readystatechange 事件也可以配合 addEventListener 使用,不过要注意,IE6~8 不支持 addEventListener
  3.  
    //为了兼容性,readystatechange 中不使用 this,而是直接使用 xhr
  4.  
    //由于兼容性的原因,最好放在 open 之前
  5.  
     
  6.  
    //xhr.readyState 是xhr的自身的状态码
  7.  
    // 0:未初始化。尚未调用 open()
  8.  
    // 1:启动。已经调用 open(),但尚未调用 send()
  9.  
    // 2:发送。已经调用 send(),但尚未接收到响应
  10.  
    // 3:接收。已经接收到部分响应数据
  11.  
    // 4:完成。已经接收到全部响应数据,而且已经可以在浏览器中使用了
  12.  
     
  13.  
    xhr.onreadystatechange = () => {
  14.  
     
  15.  
     
  16.  
    if (xhr.readyState !== 4) return;
  17.  
     
  18.  
    // HTTP CODE
  19.  
    // 获取到响应后,响应的内容会自动填充 xhr 对象的属性
  20.  
    // xhr.status:HTTP 200 404
  21.  
    // xhr.statusText:HTTP 状态说明 OK Not Found
  22.  
    if ((xhr.status >= 200) && (xhr.status < 300) || xhr.status === 304) {
  23.  
    // console.log('正常使用响应数据');
  24.  
    console.log(xhr.responseText);
  25.  
    }
  26.  
    };
2.3.准备发送请求
调用 open 并不会真正发送请求,而只是做好发送请求前的准备工作
  1.  
    xhr.open(
  2.  
    'HTTP 方法 GET、POST、PUT、DELETE',
  3.  
    '地址 URL https://www.imooc.com/api/http/search/suggest?words=js ./index.html ./index.xml ./index.txt',
  4.  
    true
  5.  
    );
  6.  
    //由于兼容性的原因,最好放在 open 之前
2.4.发送请求
调用 send() 正式发送请求
send() 的参数是通过请求体携带的数据
  1.  
    xhr.send(null);
  2.  
    //传递null兼容

3.使用 Ajax 完成前后端通信

  1.  
    const url = "https://www.imooc.com/api/http/search/suggest?words=js";
  2.  
     
  3.  
    const xhr = new XMLHttpRequest();
  4.  
     
  5.  
    xhr.onreadystatechange = function () {
  6.  
    if (xhr.readyState !== 4) return;
  7.  
     
  8.  
    if ((xhr.status >= 200 && xhr.status < 300) || xhr.status === 304) {
  9.  
    console.log(xhr.responseText);
  10.  
    console.log(typeof xhr.responseText);
  11.  
    }
  12.  
    };
  13.  
     
  14.  
    xhr.open("GET", url, true);
  15.  
     
  16.  
    xhr.send(null);

3.GET请求

  • 携带数据

  • 数据编码

1.携带数据

GET 请求不能通过请求体携带数据,但可以通过请求头携带
  1.  
    const url = "https://www.imooc.com/api/http/search/suggest?words=js&username=yunmu&age=18";
  2.  
     
  3.  
    const xhr = new XMLHttpRequest();
  4.  
     
  5.  
    xhr.onreadystatechange = function () {
  6.  
    if (xhr.readyState !== 4) return;
  7.  
     
  8.  
    if ((xhr.status >= 200 && xhr.status < 300) || xhr.status === 304) {
  9.  
    console.log(xhr.responseText);
  10.  
     
  11.  
    }
  12.  
    };
  13.  
     
  14.  
    xhr.open("GET", url, true);
  15.  
    //不会报错,但不会发送数据
  16.  
    xhr.send("sex=female");
学新通
  1.  
    //类似与form表单的提交方式
  2.  
    <form action="https://www.imooc.com/api/http/search/suggest" method="get">
  3.  
    <input type="text" name="username" />
  4.  
    <input type="text" name="words" />
  5.  
    <input type="password" name="password" />
  6.  
    <input type="submit" value="提交" />
  7.  
    </form>

2.数据编码

如果携带的数据是非英文字母的话,比如说汉字,就需要编码之后再发送给后端,不然会造成乱码问题
可以使用 encodeURIComponent() 编码
  1.  
    const url = `https://www.imooc.com/api/http/search/suggest?words=${encodeURIComponent(
  2.  
    "前端"
  3.  
    )}`;
  4.  
     
  5.  
    const xhr = new XMLHttpRequest();
  6.  
     
  7.  
    xhr.onreadystatechange = function () {
  8.  
    if (xhr.readyState !== 4) return;
  9.  
     
  10.  
    if ((xhr.status >= 200 && xhr.status < 300) || xhr.status === 304) {
  11.  
    console.log(xhr.responseText);
  12.  
    }
  13.  
    };
  14.  
     
  15.  
    xhr.open("GET", url, true);
  16.  
    //不会报错,但不会发送数据
  17.  
    xhr.send();
学新通

4.POST请求

  • 携带数据

  • 数据编码

1.携带数据

POST 请求主要通过请求体携带数据,同时也可以通过请求头携带
  1.  
    // POST 请求主要通过请求体携带数据,同时也可以通过请求头携带
  2.  
    const url = 'https://www.imooc.com/api/http/search/suggest?words=js';
  3.  
     
  4.  
    const xhr = new XMLHttpRequest();
  5.  
     
  6.  
    xhr.onreadystatechange = () => {
  7.  
    if (xhr.readyState != 4) return;
  8.  
     
  9.  
    if ((xhr.status >= 200 && xhr.status < 300) || xhr.status === 304) {
  10.  
    console.log(xhr.responseText);
  11.  
    }
  12.  
    };
  13.  
     
  14.  
    xhr.open("POST", url, true);
  15.  
     
  16.  
    // 如果想发送数据,直接写在 send() 的参数位置,一般是字符串 保持与form表单传递数据格式一致
  17.  
    xhr.send('username=yunmu&age=18');
学新通
  1.  
    <form
  2.  
    action="https://www.imooc.com/api/http/search/suggest?words=js"
  3.  
    method="post"
  4.  
    >
  5.  
    <input type="text" name="username" />
  6.  
    <input type="password" name="password" />
  7.  
    <input type="submit" value="提交" />
  8.  
    </form>

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

  1.  
    xhr.send({
  2.  
    username: "yunmu",
  3.  
    age: 18
  4.  
    });
  5.  
    // [object Object]

2.数据编码

xhr.send(`username=${encodeURIComponent('云牧')}&age=18`);

5.JSON

1.初识JSON

  • JSON是什么

  • 为什么需要JSON

1.JSON 是什么

JSON 全称是 JavaScript Object Notation
Ajax 发送和接收数据的一种格`式
{"code":200,"data":[{"word":"jsp"},{"word":"js"},{"word":"json"},{"word":"js \u5165\u95e8"},{"word":"jstl"}]}

2.为什么需要 JSON

JSON 有 3 种形式,每种形式的写法都和 JS 中的数据类型很像,可以很轻松的和 JS 中的数据类型互相转换
  1.  
    // JS->JSON->PHP/Java
  2.  
    // PHP/Java->JSON->JS

2.JSON的3种形式

  • 简单值形式

  • 对象形式

  • 数组形式

1.简单值形式

json文件后缀为.json
JSON 的简单值形式就对应着 JS 中的基础数据类型
数字、字符串、布尔值、null
  1.  
    const xhr = new XMLHttpRequest();
  2.  
     
  3.  
    xhr.onreadystatechange = function () {
  4.  
    if (xhr.readyState !== 4) return;
  5.  
     
  6.  
    if ((xhr.status >= 200 && xhr.status < 300) || xhr.status === 304) {
  7.  
    console.log(xhr.responseText);
  8.  
    console.log(typeof xhr.responseText);
  9.  
    }
  10.  
    };
  11.  
     
  12.  
    //请求本地的json数据
  13.  
    xhr.open("GET", "./plain.json", true);
  14.  
     
  15.  
    xhr.send(null);
  1.  
    6
  2.  
    true
  3.  
    false
  4.  
    "str"
  5.  
    null

注意事项

① JSON 中没有 undefined 值
② JSON 中的字符串必须使用双引号
③ JSON 中是不能注释的

2.对象形式

JSON 的对象形式就对应着 JS 中的对象

注意事项

JSON 中对象的属性名必须用双引号,属性值如果是字符串也必须用双引号
JSON 中只要涉及到字符串,就必须使用双引号
不支持 undefined
  1.  
    const xhr = new XMLHttpRequest();
  2.  
     
  3.  
    xhr.onreadystatechange = function () {
  4.  
    if (xhr.readyState !== 4) return;
  5.  
     
  6.  
    if ((xhr.status >= 200 && xhr.status < 300) || xhr.status === 304) {
  7.  
    console.log(xhr.responseText);
  8.  
    console.log(typeof xhr.responseText);
  9.  
    }
  10.  
    };
  11.  
     
  12.  
     
  13.  
    xhr.open("GET", "./obj.json", true);
  14.  
     
  15.  
     
  16.  
    xhr.send(null);
  1.  
    {
  2.  
    "name":"云牧",
  3.  
    "age":18,
  4.  
    "hobbies":["唱歌","看电影"],
  5.  
    "family":{
  6.  
    "brother":"夕颜"
  7.  
    }
  8.  
    }

3.数组形式

JSON 的数组形式就对应着 JS 中的数组

注意事项

数组中的字符串必须用双引号
JSON 中只要涉及到字符串,就必须使用双引号
不支持 undefined
  1.  
    const xhr = new XMLHttpRequest();
  2.  
     
  3.  
    xhr.onreadystatechange = function () {
  4.  
    if (xhr.readyState !== 4) return;
  5.  
     
  6.  
    if ((xhr.status >= 200 && xhr.status < 300) || xhr.status === 304) {
  7.  
    console.log(xhr.responseText);
  8.  
    console.log(typeof xhr.responseText);
  9.  
    }
  10.  
    };
  11.  
     
  12.  
     
  13.  
    xhr.open("GET", "./arr.json", true);
  14.  
     
  15.  
     
  16.  
    xhr.send(null);
  1.  
    [6,null,true,false,"yunmumu"]
  2.  
    //这里不能写undefined 虽然能够获取到 但是后期转换成js对应的数据类型会有问题
  1.  
    [
  2.  
    {
  3.  
    "id": 1,
  4.  
    "username": "夕颜",
  5.  
    "comment": "666"
  6.  
    },
  7.  
    {
  8.  
    "id": 2,
  9.  
    "username": "云牧",
  10.  
    "comment": "999 6翻了"
  11.  
    }
  12.  
    ]

3.JSON的常用方法

  • JSON.parse()

  • JSON.stringify()

  • 使用JSON.parse()和JSON.stringify()封装localStorage

1.JSON.parse()

JSON.parse() 可以将 JSON 格式的字符串解析成 JS 中的对应值
一定要是合法的 JSON 字符串,否则会报错
  1.  
    const xhr = new XMLHttpRequest();
  2.  
     
  3.  
    xhr.onreadystatechange = function () {
  4.  
    if (xhr.readyState !== 4) return;
  5.  
     
  6.  
    if ((xhr.status >= 200 && xhr.status < 300) || xhr.status === 304) {
  7.  
    console.log(JSON.parse(xhr.responseText));
  8.  
    console.log(JSON.parse(xhr.responseText).data);
  9.  
    console.log(xhr.responseText);
  10.  
    }
  11.  
    };
  12.  
     
  13.  
    xhr.open("GET", "https://www.imooc.com/api/http/search/suggest?words=js", true);
  14.  
    xhr.open("GET", "./index.json", true);
  15.  
     
  16.  
    xhr.send(null);

2.JSON.stringify()

JSON.stringify() 可以将 JS 的基本数据类型、对象或者数组转换成 JSON 格式的字符串
  1.  
    const xhr = new XMLHttpRequest();
  2.  
     
  3.  
    xhr.onreadystatechange = function () {
  4.  
    if (xhr.readyState !== 4) return;
  5.  
     
  6.  
    if ((xhr.status >= 200 && xhr.status < 300) || xhr.status === 304) {
  7.  
     
  8.  
    console.log(xhr.responseText);
  9.  
    }
  10.  
    };
  11.  
     
  12.  
    xhr.open("POST", "https://www.imooc.com/api/http/search/suggest?words=js", true);
  13.  
     
  14.  
    //xhr.send({
  15.  
    //username:"yunmu",
  16.  
    //age:18
  17.  
    //});
  18.  
    console.log(
  19.  
    JSON.stringify({
  20.  
    username: "yunmu",
  21.  
    age: 18,
  22.  
    })
  23.  
    );
  24.  
     
  25.  
    xhr.send(
  26.  
    JSON.stringify({
  27.  
    username: "yunmu",
  28.  
    age: 18,
  29.  
    })
  30.  
    );

3.使用 JSON.parse() 和 JSON.stringify() 封装 localStorage

  1.  
    const Storage = window.localStorage;
  2.  
    // 设置
  3.  
    const set = (name,value) => {
  4.  
    Storage.setItem(name, JSON.stringify(value));
  5.  
    }
  6.  
     
  7.  
    // 获取
  8.  
    const get = (name) => {
  9.  
    return JSON.parse(Storage.getItem(name))
  10.  
    }
  11.  
     
  12.  
    // 删除
  13.  
    const remove = (name) => {
  14.  
    Storage.removeItem(name)
  15.  
    }
  16.  
     
  17.  
    // 清空
  18.  
    const clear = () => {
  19.  
    Storage.clear();
  20.  
    }
  21.  
     
  22.  
    export {set, get, remove, clear};
  1.  
    import {set, get, remove, clear} from "./localStorage.js";
  2.  
     
  3.  
    set("user1",{
  4.  
    name:"夕颜",
  5.  
    school:"中心小学",
  6.  
    feature:"憨憨"
  7.  
    })
  8.  
    set("user2",{
  9.  
    name:"云牧",
  10.  
    school:"中心大学",
  11.  
    feature:"比憨憨聪明"
  12.  
    })
  13.  
     
  14.  
     
  15.  
    console.log(get("user1"));
  16.  
    console.log(get("user2"));

6.跨域

  • 跨域是什么

  • 什么是不同域,什么是同域

  • 跨域请求为什么会被阻止

  • 跨域解决方案

1.跨域是什么

  1.  
    // 同域,不是跨域
  2.  
    //const url = './index.html';
  3.  
     
  4.  
     
  5.  
    // 不同域,跨域,被浏览器阻止
  6.  
    const url = 'https://www.百度.com';
  7.  
    const xhr = new XMLHttpRequest();
  8.  
     
  9.  
     
  10.  
    // 向一个域发送请求,如果要请求的域和当前域是不同域,就叫跨域
  11.  
    // 不同域之间的请求,就是跨域请求
  12.  
     
  13.  
    xhr.onreadystatechange = () => {
  14.  
    if (xhr.readyState != 4) return;
  15.  
     
  16.  
    if ((xhr.status >= 200 && xhr.status < 300) || xhr.status === 304) {
  17.  
    console.log(xhr.responseText);
  18.  
    }
  19.  
    };
  20.  
     
  21.  
    xhr.open('GET', url, true);
  22.  
     
  23.  
    xhr.send(null);

2.什么是不同域,什么是同域

https(协议): //www.shiguangkey.com(域名):443(端口号)/course/list(路径)
协议、域名、端口号,任何一个不一样,就是不同域
与路径无关,路径一不一样无所谓

不同域

  1.  
    https://www.shiguangkey.com:443/course/list
  2.  
    http://www.shiguangkey.com:80/course/list
  1.  
    http://www.shiguangkey.com:80/course/list
  2.  
    http://m.shiguangkey.com:80/course/list
  3.  
    http://shiguangkey.com:80/course/list

同域

  1.  
    http://shiguangkey.com:80
  2.  
    http://shiguangkey.com:80/course/list

3.跨域请求为什么会被阻止

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

4.跨域解决方案

① CORS 跨域资源共享
② JSONP
优先使用 CORS 跨域资源共享,如果浏览器不支持 CORS 的话,再使用 JSONP

4.CORS 跨域资源共享

  • CORS 是什么

  • 使用CORS 跨域的过程

  • CORS的兼容性

1.CORS 是什么

  1.  
    //const url = 'https://www.百度.com';
  2.  
     
  3.  
    const url = 'https://www.imooc.com/api/http/search/suggest?words=js';
  4.  
    const xhr = new XMLHttpRequest();
  5.  
     
  6.  
    xhr.onreadystatechange = () => {
  7.  
    if (xhr.readyState != 4) return;
  8.  
     
  9.  
    if ((xhr.status >= 200 && xhr.status < 300) || xhr.status === 304) {
  10.  
    console.log(xhr.responseText);
  11.  
    }
  12.  
    };
  13.  
     
  14.  
    xhr.open('GET', url, true);
  15.  
     
  16.  
    xhr.send(null);

**Access-Control-Allow-Origin: ***

表明允许所有的域名来跨域请求它,* 是通配符,没有任何限制
学新通

只允许指定域名的跨域请求

Access-Control-Allow-Origin: http://127.0.0.1:5500

2.使用 CORS 跨域的过程

① 浏览器发送请求
② 后端在响应头中添加 Access-Control-Allow-Origin 头信息
③ 浏览器接收到响应
④ 如果是同域下的请求,浏览器不会额外做什么,这次前后端通信就圆满完成了
⑤ 如果是跨域请求,浏览器会从响应头中查找是否允许跨域访问
⑥ 如果允许跨域,通信圆满完成
⑦ 如果没找到或不包含想要跨域的域名,就丢弃响应结果

3.CORS 的兼容性

IE10 及以上版本的浏览器可以正常使用 CORS

5.JSONP

  • JSONP的原理

  • 使用JSONP 实现跨域

1.JSONP 的原理

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

2.使用 JSONP 实现跨域

服务器端准备好 JSONP 接口
 https://www.imooc.com/api/http/jsonp?callback=handleResponse
学新通
手动加载 JSONP 接口或动态加载 JSONP 接口
  1.  
    <script>
  2.  
    //声明函数
  3.  
    const handleResponse = (data) => {
  4.  
    console.log(data);
  5.  
    }
  6.  
    // 动态加载 JSONP 接口
  7.  
    // const script = document.createElement("script");
  8.  
    // script.src =
  9.  
    // "https://www.imooc.com/api/http/jsonp?callback=handleResponse";
  10.  
    // document.body.appendChild(script);
  11.  
     
  12.  
    </script>
  13.  
     
  14.  
    //手动加载 JSONP接口
  15.  
    <script src="https://www.imooc.com/api/http/jsonp?callback=handleResponse"></script>

7.XHR对象

XHR的属性

  • responseType和response属性

  • timeout属性

  • withCredentials 属性

1.responseType 和 response 属性

  1.  
    const url =
  2.  
    "https://www.imooc.com/api/http/search/suggest?words=js";
  3.  
    const xhr = new XMLHttpRequest();
  4.  
     
  5.  
    xhr.onreadystatechange = () => {
  6.  
    if (xhr.readyState != 4) return;
  7.  
     
  8.  
    if ((xhr.status >= 200 && xhr.status < 300) || xhr.status === 304) {
  9.  
    // 文本形式的响应内容
  10.  
    // responseText 只能在没有设置 responseType 或者 responseType = "" 或 "text" 的时候才能使用
  11.  
    // console.log('responseText:', xhr.responseText);
  12.  
     
  13.  
    //可以用来替代 responseText
  14.  
    console.log('response:', xhr.response);
  15.  
    }
  16.  
    };
  17.  
     
  18.  
    xhr.open("GET", url, true);
  19.  
     
  20.  
    //默认的响应类型
  21.  
    //xhr.responseType = "";
  22.  
    //xhr.responseType = "text";
  23.  
    xhr.responseType = 'json';
  24.  
     
  25.  
    xhr.send(null);
IE6~9 不支持,IE10 开始支持

2.timeout 属性

设置请求的超时时间(单位 ms)
  1.  
    const url = 'https://www.imooc.com/api/http/search/suggest?words=js';
  2.  
    const xhr = new XMLHttpRequest();
  3.  
     
  4.  
    xhr.onreadystatechange = () => {
  5.  
    if (xhr.readyState != 4) return;
  6.  
     
  7.  
    if ((xhr.status >= 200 && xhr.status < 300) || xhr.status === 304) {
  8.  
     
  9.  
    console.log(xhr.response);
  10.  
    }
  11.  
    };
  12.  
     
  13.  
    xhr.open("GET", url, true);
  14.  
     
  15.  
    xhr.timeout = 10000;
  16.  
     
  17.  
    xhr.send(null);
IE6~7 不支持,IE8 开始支持

3.withCredentials 属性

指定使用 Ajax 发送请求时是否携带 Cookie
使用 Ajax 发送请求,默认情况下,同域时,会携带 Cookie;
跨域时,不会 如果要跨域携带 xhr.withCredentials = true;
最终能否成功跨域携带 Cookie,还要看服务器同不同意
  1.  
    //const url = './index.html';
  2.  
    const url = 'https://www.imooc.com/api/http/search/suggest?words=js';
  3.  
     
  4.  
     
  5.  
    const xhr = new XMLHttpRequest();
  6.  
     
  7.  
    xhr.onreadystatechange = () => {
  8.  
    if (xhr.readyState != 4) return;
  9.  
     
  10.  
    if ((xhr.status >= 200 && xhr.status < 300) || xhr.status === 304) {
  11.  
     
  12.  
    console.log(xhr.response);
  13.  
    }
  14.  
    };
  15.  
     
  16.  
    xhr.open("GET", url, true);
  17.  
     
  18.  
    xhr.withCredentials = true;
  19.  
     
  20.  
    xhr.send(null);
IE6~9 不支持,IE10 开始支持

XHR的方法

  • abort()

  • setRequestHeader()

1.abort()

终止当前请求
一般配合 abort 事件一起使用
  1.  
    const url = 'https://www.imooc.com/api/http/search/suggest?words=js';
  2.  
     
  3.  
     
  4.  
    const xhr = new XMLHttpRequest();
  5.  
     
  6.  
    xhr.onreadystatechange = () => {
  7.  
    if (xhr.readyState != 4) return;
  8.  
     
  9.  
    if ((xhr.status >= 200 && xhr.status < 300) || xhr.status === 304) {
  10.  
     
  11.  
    console.log(xhr.response);
  12.  
    }
  13.  
    };
  14.  
     
  15.  
    xhr.open("GET", url, true);
  16.  
     
  17.  
    xhr.abort();//这里不能终止请求
  18.  
     
  19.  
    xhr.send(null);
  20.  
     
  21.  
    xhr.abort();

2.setRequestHeader()

可以设置请求头信息
xhr.setRequestHeader(头部字段的名称, 头部字段的值);
  1.  
    //const url = 'https://www.imooc.com/api/http/search/suggest?words=js';
  2.  
    const url = 'https://www.imooc.com/api/http/json/search/suggest?words=js';
  3.  
     
  4.  
    const xhr = new XMLHttpRequest();
  5.  
     
  6.  
    xhr.onreadystatechange = () => {
  7.  
    if (xhr.readyState != 4) return;
  8.  
     
  9.  
    if ((xhr.status >= 200 && xhr.status < 300) || xhr.status === 304) {
  10.  
     
  11.  
    console.log(xhr.response);
  12.  
    }
  13.  
    };
  14.  
     
  15.  
    xhr.open("POST", url, true);
  16.  
     
  17.  
    //请求头中的 Content-Type 字段用来告诉服务器,浏览器发送的数据是什么格式的
  18.  
    //xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
  19.  
    xhr.setRequestHeader('Content-Type', 'application/json');
  20.  
     
  21.  
    //xhr.send('username=alex&age=18');
  22.  
    xhr.send(
  23.  
    JSON.stringify({
  24.  
    username: "yunmu"
  25.  
    })
  26.  
    );

XHR的事件

  • load事件

  • error 事件

  • abort事件

  • timeout 事件

1.load 事件

响应数据可用时触发
  1.  
    const url = "https://www.imooc.com/api/http/search/suggest?words=js";
  2.  
    const xhr = new XMLHttpRequest();
  3.  
     
  4.  
    // xhr.onload = () => {
  5.  
    // if ((xhr.status >= 200 && xhr.status < 300) || xhr.status === 304) {
  6.  
    // console.log(xhr.response);
  7.  
    // }
  8.  
    // };
  9.  
     
  10.  
    xhr.addEventListener(
  11.  
    "load",
  12.  
    () => {
  13.  
    if ((xhr.status >= 200 && xhr.status < 300) || xhr.status === 304) {
  14.  
    console.log(xhr.response);
  15.  
    }
  16.  
    },
  17.  
    false
  18.  
    );
  19.  
     
  20.  
    xhr.open("GET", url, true);
  21.  
     
  22.  
    xhr.send(null);
IE6~8 不支持 load 事件

2.error 事件

请求发生错误时触发
  1.  
    const url = "https://www.imooc.com/api/http/search/suggest?words=js";
  2.  
    //const url = "https://www.iimooc.com/api/http/search/suggest?words=js";
  3.  
     
  4.  
    const xhr = new XMLHttpRequest();
  5.  
     
  6.  
    xhr.addEventListener(
  7.  
    "load",
  8.  
    () => {
  9.  
    if ((xhr.status >= 200 && xhr.status < 300) || xhr.status === 304) {
  10.  
    console.log(xhr.response);
  11.  
    }
  12.  
    },
  13.  
    false
  14.  
    );
  15.  
    xhr.addEventListener(
  16.  
    "error",
  17.  
    () => {
  18.  
    console.log("error");
  19.  
    },
  20.  
    false
  21.  
    );
  22.  
     
  23.  
    xhr.open("GET", url, true);
  24.  
     
  25.  
    xhr.send(null);
IE10 开始支持

3.abort 事件

调用 abort() 终止请求时触发
  1.  
    const url = "https://www.imooc.com/api/http/search/suggest?words=js";
  2.  
     
  3.  
    const xhr = new XMLHttpRequest();
  4.  
     
  5.  
    xhr.addEventListener(
  6.  
    "load",
  7.  
    () => {
  8.  
    if ((xhr.status >= 200 && xhr.status < 300) || xhr.status === 304) {
  9.  
    console.log(xhr.response);
  10.  
    }
  11.  
    },
  12.  
    false
  13.  
    );
  14.  
    xhr.addEventListener(
  15.  
    "abort",
  16.  
    () => {
  17.  
    console.log("abort");
  18.  
    },
  19.  
    false
  20.  
    );
  21.  
     
  22.  
    xhr.open("GET", url, true);
  23.  
     
  24.  
    xhr.send(null);
  25.  
     
  26.  
    xhr.abort();
IE10 开始支持

4.timeout 事件

请求超时后触发
  1.  
    const url = 'https://www.imooc.com/api/http/search/suggest?words=js';
  2.  
     
  3.  
    const xhr = new XMLHttpRequest();
  4.  
     
  5.  
    xhr.addEventListener(
  6.  
    'load',
  7.  
    () => {
  8.  
    if ((xhr.status >= 200 && xhr.status < 300) || xhr.status === 304) {
  9.  
    console.log(xhr.response);
  10.  
    }
  11.  
    },
  12.  
    false
  13.  
    );
  14.  
    xhr.addEventListener(
  15.  
    'timeout',
  16.  
    () => {
  17.  
    console.log('timeout');
  18.  
    },
  19.  
    false
  20.  
    );
  21.  
     
  22.  
    xhr.open('GET', url, true);
  23.  
     
  24.  
    xhr.timeout = 10;
  25.  
     
  26.  
    xhr.send(null);
IE8 开始支持
学新通

8.封装ajax

1.使用 Ajax 提交表单

  1.  
    <form
  2.  
    id="login"
  3.  
    action="https://www.imooc.com/api/http/search/suggest?words=js"
  4.  
    method="POST"
  5.  
    enctype="multipart/form-data"
  6.  
    >
  7.  
    <input type="text" name="username" placeholder="用户名" />
  8.  
    <input type="password" name="password" placeholder="密码" />
  9.  
    <input id="submit" type="submit" value="登录" />
  10.  
    </form>
  11.  
     
  12.  
    <script>
  13.  
    const login = document.getElementById('login');
  14.  
    // console.log(login.username);
  15.  
    // console.log(login.password);
  16.  
    const { username, password } = login;
  17.  
    const btn = document.getElementById('submit');
  18.  
     
  19.  
    const url = 'https://www.imooc.com/api/http/search/suggest?words=js';
  20.  
     
  21.  
    btn.addEventListener(
  22.  
    "click",
  23.  
    e => {
  24.  
    // 阻止表单自动提交
  25.  
    e.preventDefault();
  26.  
     
  27.  
    // 表单数据验证
  28.  
     
  29.  
    // 发送 Ajax 请求
  30.  
    const xhr = new XMLHttpRequest();
  31.  
     
  32.  
    xhr.addEventListener(
  33.  
    'load',
  34.  
    () => {
  35.  
    if (
  36.  
    (xhr.status >= 200 && xhr.status < 300) ||
  37.  
    xhr.status === 304
  38.  
    ) {
  39.  
    console.log(xhr.response);
  40.  
    }
  41.  
    },
  42.  
    false
  43.  
    );
  44.  
     
  45.  
    xhr.open('POST', url, true);
  46.  
     
  47.  
    // 组装数据
  48.  
    // const data = `username=${username.value}&password=${password.value}`;
  49.  
     
  50.  
    // FormData 可用于发送表单数据
  51.  
    const data = new FormData(login);
  52.  
    // console.log(data);
  53.  
    data.append('age', 18);
  54.  
    data.append('sex', 'male');
  55.  
    // for (const item of data) {
  56.  
    // console.log(item);
  57.  
    // }
  58.  
     
  59.  
    // xhr.setRequestHeader(
  60.  
    // 'Content-Type',
  61.  
    // 'application/x-www-form-urlencoded'
  62.  
    // );
  63.  
     
  64.  
    xhr.send(data);
  65.  
     
  66.  
    },
  67.  
    false
  68.  
    );
  69.  
     
  70.  
    </script>

2.FormData 的基本用法

  1.  
    // 通过 HTML 表单元素创建 FormData 对象
  2.  
    // const fd = new FormData(表单元素);
  3.  
    // xhr.send(fd);
  4.  
     
  5.  
    // 通过 append() 方法添加数据
  6.  
    // const fd = new FormData(表单元素);
  7.  
    // fd.append("age", 18);
  8.  
    // fd.append("sex", "male");
  9.  
    // xhr.send(fd);
  10.  
     
  11.  
    // IE10 及以上可以支持

3.封装ajax

ajax

  1.  
     
  2.  
    //默认参数
  3.  
    import DEFAULTS from "./deafaults.js";
  4.  
    //工具函数
  5.  
    import { serialize, addURLData, serializeJSON} from "./utils.js";
  6.  
    //常量
  7.  
    import {
  8.  
    HTTP_GET,
  9.  
    COTENT_TYPE_FORM_URLENCODED,
  10.  
    COTENT_TYPE_JSON,
  11.  
    } from "./constants.js";
  12.  
     
  13.  
    //Ajax类
  14.  
    class Ajax {
  15.  
    constructor(url, options) {
  16.  
    this.url = url;
  17.  
    this.options = Object.assign({}, DEFAULTS, options);
  18.  
     
  19.  
    //初始化
  20.  
    this.init();
  21.  
    }
  22.  
     
  23.  
    //初始化
  24.  
    init() {
  25.  
    const xhr = new XMLHttpRequest();
  26.  
     
  27.  
    this.xhr = xhr;
  28.  
     
  29.  
    //绑定事件的响应程序
  30.  
    this.bindEvent();
  31.  
     
  32.  
    //准备发送请求
  33.  
    xhr.open(this.options.method, this.url this.addParam(), true);
  34.  
     
  35.  
    //设置responseType
  36.  
    this.setResponseType();
  37.  
     
  38.  
    //设置超时
  39.  
    this.setTimeout();
  40.  
     
  41.  
    //设置跨域是否携带 cookie
  42.  
    this.setCookie();
  43.  
     
  44.  
    //发送请求
  45.  
    this.sendData();
  46.  
    }
  47.  
     
  48.  
    //绑定事件的响应程序
  49.  
    bindEvent() {
  50.  
    const xhr = this.xhr;
  51.  
     
  52.  
    const { success, httpCodeError, error, abort, timeout } = this.options;
  53.  
     
  54.  
    //load
  55.  
    xhr.addEventListener("load", () => {
  56.  
    if (this.ok()) {
  57.  
    success(xhr.response, xhr);
  58.  
    } else {
  59.  
    httpCodeError(xhr.status, xhr);
  60.  
    }
  61.  
    });
  62.  
     
  63.  
    // error
  64.  
    xhr.addEventListener("error", () => {
  65.  
    error(xhr);
  66.  
    });
  67.  
     
  68.  
    //abort
  69.  
    xhr.addEventListener("abort", () => {
  70.  
    abort(xhr);
  71.  
    });
  72.  
     
  73.  
    // timeout
  74.  
    xhr.addEventListener("timeout", () => {
  75.  
    timeout(xhr);
  76.  
    });
  77.  
    }
  78.  
     
  79.  
    //检测状态码是否正常
  80.  
    ok() {
  81.  
    const xhr = this.xhr;
  82.  
    return (xhr.status >= 200 && xhr.status < 300) || xhr.status === 304;
  83.  
    }
  84.  
     
  85.  
    // 在地址上添加数据
  86.  
    addParam() {
  87.  
    const { params } = this.options;
  88.  
     
  89.  
    if (!params) return "";
  90.  
     
  91.  
    return addURLData(this.url, serialize(params));
  92.  
    }
  93.  
     
  94.  
    // 设置responseType
  95.  
    setResponseType() {
  96.  
    this.xhr.responseType = this.options.responseType;
  97.  
    }
  98.  
     
  99.  
    //设置超时
  100.  
    setTimeout() {
  101.  
    const { timeoutTime } = this.options;
  102.  
     
  103.  
    if (timeoutTime > 0) {
  104.  
    this.xhr.timeout = timeoutTime;
  105.  
    }
  106.  
    }
  107.  
     
  108.  
    //设置跨域是否携带 cookie
  109.  
    setCookie() {
  110.  
    if (this.options.withCredentials) {
  111.  
    this.xhr.withCredentials = true;
  112.  
    }
  113.  
    }
  114.  
     
  115.  
    //发送请求
  116.  
    sendData() {
  117.  
    const xhr = this.xhr;
  118.  
     
  119.  
    if (!this.isSendData()) {
  120.  
    return xhr.send(null);
  121.  
    }
  122.  
     
  123.  
    let resultData = null;
  124.  
    const { data } = this.options;
  125.  
     
  126.  
    // 发送 FormData 数据
  127.  
    if(this.isFormData()){
  128.  
    resultData = data;
  129.  
     
  130.  
    }else if(this.isFormURLEncodedData()){
  131.  
    //发送form-urlencoded格式的数据
  132.  
    this.setContentType(COTENT_TYPE_FORM_URLENCODED)
  133.  
    resultData = serialize(data);
  134.  
     
  135.  
    }else if(this.JSONData()){
  136.  
    this.setContentType(COTENT_TYPE_JSON)
  137.  
    //发送JSON格式的数据
  138.  
    resultData = serializeJSON(data);
  139.  
    }else{
  140.  
    this.setContentType();
  141.  
    //其他格式的数据
  142.  
    resultData = data;
  143.  
    }
  144.  
     
  145.  
     
  146.  
    return xhr.send(resultData)
  147.  
    }
  148.  
     
  149.  
    // 是否需要使用sendData发送数据
  150.  
    isSendData() {
  151.  
    const { data, method } = this.options;
  152.  
     
  153.  
    if (!data) return false;
  154.  
     
  155.  
    if (method.toLowerCase() === HTTP_GET.toLowerCase()) return false;
  156.  
     
  157.  
    return true;
  158.  
    }
  159.  
     
  160.  
    //判断是否 发送 FormData格式的数据
  161.  
    isFormData(){
  162.  
    return this.options.data instanceof FormData;
  163.  
    }
  164.  
     
  165.  
    //判断是否发送 application/x-www-form-urlencoded 格式的数据
  166.  
    isFormURLEncodedData(){
  167.  
    return this.options.cotentType.toLowerCase().includes(COTENT_TYPE_FORM_URLENCODED);
  168.  
    }
  169.  
     
  170.  
    //判断是否发送的是否是 JSON 格式的数据
  171.  
    JSONData(){
  172.  
    return this.options.cotentType.toLowerCase().includes(COTENT_TYPE_JSON);
  173.  
    }
  174.  
     
  175.  
    // 设置发送的数据格式ContentType
  176.  
    setContentType(contentType = this.options.conetntType){
  177.  
    if(!contentType) return;
  178.  
     
  179.  
    this.xhr.setRequestHeader("Content-Type", contentType);
  180.  
    }
  181.  
     
  182.  
    //获取XHR对象
  183.  
    getXHR(){
  184.  
    return this.xhr;
  185.  
    }
  186.  
    }
  187.  
     
  188.  
    export default Ajax;
  189.  
     
  190.  
    //new Ajax()

deafaults

  1.  
    //默认参数
  2.  
    import {HTTP_GET, COTENT_TYPE_FORM_URLENCODED, COTENT_TYPE_JSON} from "./constants.js";
  3.  
    const DEFAULTS = {
  4.  
    method: HTTP_GET,
  5.  
     
  6.  
    //请求头携带的数据
  7.  
    params: null,
  8.  
    //params:{
  9.  
    // username:yunmu,
  10.  
    // age:18
  11.  
    //}
  12.  
     
  13.  
    //username=yunmu&age=18
  14.  
     
  15.  
    //请求体携带数据
  16.  
    data: null,
  17.  
     
  18.  
    //data:{
  19.  
    // username:yunmu,
  20.  
    // age:18
  21.  
    //}
  22.  
     
  23.  
    //data: FormData数据
  24.  
     
  25.  
    // 属性
  26.  
    cotentType: COTENT_TYPE_FORM_URLENCODED,
  27.  
    responseType:"",
  28.  
    timeoutTime:0,
  29.  
    withCredentials:false,
  30.  
     
  31.  
    //方法
  32.  
    success(){},
  33.  
    httpCodeError(){},
  34.  
    error(){},
  35.  
    abort(){},
  36.  
    timeout(){}
  37.  
    }
  38.  
     
  39.  
    export default DEFAULTS;

utils

  1.  
    // 工具函数
  2.  
    const serialize = param => {
  3.  
    const results = [];
  4.  
     
  5.  
    for(const [key, value] of Object.entries(param)){
  6.  
     
  7.  
    results.push(`${encodeURIComponent(key)}=${encodeURIComponent(value)}`);
  8.  
     
  9.  
    }
  10.  
     
  11.  
    return results.join("&");
  12.  
     
  13.  
    //["username=yunmu","age=18"]
  14.  
    //"username=yunmu"&"age=18"
  15.  
    }
  16.  
     
  17.  
    //www,百度.com&
  18.  
     
  19.  
    //给URL添加参数
  20.  
    const addURLData = (url, data) => {
  21.  
    if(!data) return "";
  22.  
     
  23.  
    const mark = url.includes("?") ? "&" : "?";
  24.  
     
  25.  
    return `${mark}${data}`;
  26.  
    }
  27.  
     
  28.  
     
  29.  
     
  30.  
    //序列化成JSON格式的字符串
  31.  
    const serializeJSON = (data) => {
  32.  
    return JSON.stringify(data);
  33.  
    }
  34.  
     
  35.  
    export {serialize, addURLData, serializeJSON};

constants

  1.  
    //常量模块
  2.  
    export const HTTP_GET = "GET";
  3.  
     
  4.  
    export const COTENT_TYPE_FORM_URLENCODED = "application/x-www-form-urlencoded";
  5.  
     
  6.  
    export const COTENT_TYPE_JSON = "application/json";
  7.  
     
  8.  
     
  9.  
     
  10.  
    export const ERROR_HTTP_CODE = 1;
  11.  
    export const ERROR_HTTP_CODE_TEXT = 'HTTP 状态码异常';
  12.  
    export const ERROR_REQUEST = 2;
  13.  
    export const ERROR_REQUEST_TEXT = '请求被阻止';
  14.  
    export const ERROR_TIMEOUT = 3;
  15.  
    export const ERROR_TIMEOUT_TEXT = '请求超时';
  16.  
    export const ERROR_ABORT = 4;
  17.  
    export const ERROR_ABORT_TEXT = '请求终止';

index

  1.  
    import Ajax from "./ajax.js";
  2.  
     
  3.  
    //常量
  4.  
    import {
  5.  
    ERROR_HTTP_CODE,
  6.  
    ERROR_HTTP_CODE_TEXT,
  7.  
    ERROR_REQUEST,
  8.  
    ERROR_REQUEST_TEXT,
  9.  
    ERROR_TIMEOUT,
  10.  
    ERROR_TIMEOUT_TEXT,
  11.  
    ERROR_ABORT,
  12.  
    ERROR_ABORT_TEXT,
  13.  
    } from "./constants.js";
  14.  
     
  15.  
    const ajax = (url, options) => {
  16.  
    //return new Ajax(url, options).getXHR();
  17.  
    let xhr;
  18.  
    const p = new Promise((resolve, reject) => {
  19.  
    xhr = new Ajax(url, {
  20.  
    ...options,
  21.  
    ...{
  22.  
    success(response) {
  23.  
    resolve(response);
  24.  
    },
  25.  
    httpCodeError(status) {
  26.  
    reject({
  27.  
    type: ERROR_HTTP_CODE,
  28.  
    text: `ERROR_HTTP_CODE_TEXT:${status}`,
  29.  
    });
  30.  
    },
  31.  
     
  32.  
    error() {
  33.  
    reject({
  34.  
    type: ERROR_REQUEST,
  35.  
    text: ERROR_REQUEST_TEXT,
  36.  
    });
  37.  
    },
  38.  
     
  39.  
    abort() {
  40.  
    reject({
  41.  
    type: ERROR_ABORT,
  42.  
    text: ERROR_ABORT_TEXT,
  43.  
    });
  44.  
    },
  45.  
     
  46.  
    timeout() {
  47.  
    reject({
  48.  
    type: ERROR_TIMEOUT,
  49.  
    text: ERROR_TIMEOUT_TEXT,
  50.  
    });
  51.  
    },
  52.  
    },
  53.  
    }).getXHR();
  54.  
    });
  55.  
     
  56.  
     
  57.  
    p.xhr = xhr;
  58.  
    p.ERROR_HTTP_CODE = ERROR_HTTP_CODE;
  59.  
    p.ERROR_REQUEST = ERROR_REQUEST;
  60.  
    p.ERROR_TIMEOUT = ERROR_TIMEOUT;
  61.  
    p.ERROR_ABORT = ERROR_ABORT;
  62.  
     
  63.  
    return p;
  64.  
    };
  65.  
     
  66.  
    const get = (url, options) => {
  67.  
    return ajax(url, { ...options, method: "GET" });
  68.  
    };
  69.  
     
  70.  
    const post = (url, options) => {
  71.  
    return ajax(url, { ...options, method: "POST" });
  72.  
    };
  73.  
     
  74.  
    const getJSON = (url, options) => {
  75.  
    return ajax(url, { ...options, method: "GET", responseType: "json" });
  76.  
    };
  77.  
     
  78.  
    export { ajax, get, post, getJSON };

9.ajax的应用

搜索提示

  1.  
    <input id="search" type="text" />
  2.  
    <ul id="result"></ul>
  3.  
     
  4.  
    <script type="module">
  5.  
    import { getJSON } from './ajax/index.js';
  6.  
     
  7.  
    const searchInput = document.getElementById('search');
  8.  
    const resultList = document.getElementById('result');
  9.  
     
  10.  
    const url = 'https://www.imooc.com/api/http/search/suggest?words=';
  11.  
     
  12.  
    const handleInputEvent = () => {
  13.  
    if (searchInput.value.trim() !== '') {
  14.  
    getJSON(`${url}${searchInput.value}`)
  15.  
    .then(response => {
  16.  
    console.log(response);
  17.  
    // [{word: "jsp"}]
  18.  
     
  19.  
    let html = '';
  20.  
    for (const item of response.data) {
  21.  
    html = `<li>${item.word}</li>`;
  22.  
    }
  23.  
     
  24.  
    resultList.innerHTML = html;
  25.  
     
  26.  
    resultList.style.display = '';
  27.  
     
  28.  
    // resultList.innerHTML = '<li>jsp</li><li>js</li>';
  29.  
    })
  30.  
    .catch(err => {
  31.  
    console.log(err);
  32.  
    });
  33.  
    } else {
  34.  
    resultList.innerHTML = '';
  35.  
    resultList.style.display = 'none';
  36.  
    }
  37.  
    };
  38.  
     
  39.  
    let timer = null;
  40.  
    // IE9 开始支持
  41.  
    searchInput.addEventListener(
  42.  
    'input',
  43.  
    () => {
  44.  
    // handleInputEvent();
  45.  
     
  46.  
    if (timer) {
  47.  
    clearTimeout(timer);
  48.  
    }
  49.  
    // jsa
  50.  
    timer = setTimeout(handleInputEvent, 500);
  51.  
    },
  52.  
    false
  53.  
    );
  54.  
    </script>

二级菜单

  1.  
     
  2.  
    <!DOCTYPE html>
  3.  
    <html lang="en">
  4.  
    <head>
  5.  
    <meta charset="UTF-8" />
  6.  
    <title>二级菜单</title>
  7.  
    <style>
  8.  
    /* css reset */
  9.  
    * {
  10.  
    padding: 0;
  11.  
    margin: 0;
  12.  
    }
  13.  
    li {
  14.  
    list-style: none;
  15.  
    }
  16.  
     
  17.  
    /* menu */
  18.  
    .menu {
  19.  
    width: 100px;
  20.  
    background-color: rgba(0, 0, 0, 0.1);
  21.  
    margin: 10px;
  22.  
    }
  23.  
    .menu-item {
  24.  
    position: relative;
  25.  
    padding: 5px;
  26.  
    cursor: pointer;
  27.  
    }
  28.  
    .menu-content {
  29.  
    display: none;
  30.  
    position: absolute;
  31.  
    left: 100%;
  32.  
    top: 0;
  33.  
    width: 200px;
  34.  
    height: 100px;
  35.  
    padding: 0 5px;
  36.  
    background-color: rgba(0, 0, 0, 0.1);
  37.  
    }
  38.  
    .menu-item:hover {
  39.  
    background-color: rgba(0, 0, 0, 0.4);
  40.  
    }
  41.  
    .menu-item:hover .menu-content {
  42.  
    display: block;
  43.  
    }
  44.  
    .menu-loading {
  45.  
    margin: 45px 0 0 92px;
  46.  
    }
  47.  
    </style>
  48.  
    </head>
  49.  
    <body>
  50.  
    <ul id="menu" class="menu">
  51.  
    <!-- <li class="menu-item" data-key="hot" data-done="done">
  52.  
    <span>热门</span>
  53.  
    <div class="menu-content">
  54.  
    <p><img class="menu-loading" src="https://blog.csdn.net/zhiqinzhe/article/details/loading.gif" alt="加载中" /></p>
  55.  
    </div>
  56.  
    </li> -->
  57.  
    </ul>
  58.  
     
  59.  
    <script type="module">
  60.  
    // https://www.imooc.com/api/mall-PC/index/menu/hot
  61.  
    // https://www.imooc.com/api/mall-PC/index/menu
  62.  
     
  63.  
    import { getJSON } from './ajax/index.js';
  64.  
    const menuURL = 'https://www.imooc.com/api/mall-PC/index/menu';
  65.  
    const menuEl = document.getElementById('menu');
  66.  
     
  67.  
    getJSON(menuURL)
  68.  
    .then(repsonse => {
  69.  
    // console.log(repsonse);
  70.  
     
  71.  
    let html = '';
  72.  
     
  73.  
    for (const item of repsonse.data) {
  74.  
    html = `
  75.  
    <li class="menu-item" data-key="${item.key}">
  76.  
    <span>${item.title}</span>
  77.  
    <div class="menu-content">
  78.  
    <p><img class="menu-loading" src="https://blog.csdn.net/zhiqinzhe/article/details/loading.gif" alt="加载中" /></p>
  79.  
    </div>
  80.  
    </li>
  81.  
    `;
  82.  
    }
  83.  
     
  84.  
    menuEl.innerHTML = html;
  85.  
     
  86.  
    // [{key: "hot", title: "热门出发地", subTitles: Array(5)}]
  87.  
     
  88.  
    // ...
  89.  
    })
  90.  
    .then(() => {
  91.  
    const items = menuEl.querySelectorAll('.menu-item');
  92.  
     
  93.  
    for (const item of items) {
  94.  
    item.addEventListener(
  95.  
    'mouseenter',
  96.  
    () => {
  97.  
    // console.log(item.getAttribute('data-key'));
  98.  
     
  99.  
    // IE11 开始支持
  100.  
    // console.log(item.dataset.key);
  101.  
     
  102.  
    if (item.dataset.done === 'done') return;
  103.  
     
  104.  
    getJSON(
  105.  
    `https://www.imooc.com/api/mall-PC/index/menu/${item.dataset.key}`
  106.  
    )
  107.  
    .then(repsonse => {
  108.  
    // console.log(repsonse);
  109.  
     
  110.  
    // [{title: "内地热门城市", cities: Array(27)}]
  111.  
     
  112.  
    item.dataset.done = 'done';
  113.  
     
  114.  
    let html = '';
  115.  
     
  116.  
    for (const item of repsonse.data) {
  117.  
    html = `<p>${item.title}</p>`;
  118.  
    }
  119.  
     
  120.  
    item.querySelector('.menu-content').innerHTML = html;
  121.  
    })
  122.  
    .catch(err => {
  123.  
    console.log(err);
  124.  
    });
  125.  
    },
  126.  
    false
  127.  
    );
  128.  
    }
  129.  
    })
  130.  
    .catch(err => {
  131.  
    console.log(err);
  132.  
    });
  133.  
    </script>
  134.  
    </body>
  135.  
    </html>

多个ajax请求并发执行

  1.  
     
  2.  
    <!DOCTYPE html>
  3.  
    <html lang="en">
  4.  
    <head>
  5.  
    <meta charset="UTF-8" />
  6.  
    <title>多个 Ajax 请求的并发执行</title>
  7.  
    <style>
  8.  
    /* css reset */
  9.  
    * {
  10.  
    padding: 0;
  11.  
    margin: 0;
  12.  
    }
  13.  
    li {
  14.  
    list-style: none;
  15.  
    }
  16.  
     
  17.  
    /* menu */
  18.  
    .menu {
  19.  
    width: 100px;
  20.  
    background-color: rgba(0, 0, 0, 0.1);
  21.  
    margin: 10px;
  22.  
    }
  23.  
    .menu-item {
  24.  
    position: relative;
  25.  
    padding: 5px;
  26.  
    cursor: pointer;
  27.  
    }
  28.  
    .menu-content {
  29.  
    display: none;
  30.  
    position: absolute;
  31.  
    left: 100%;
  32.  
    top: 0;
  33.  
    width: 200px;
  34.  
    height: 100px;
  35.  
    padding: 0 5px;
  36.  
    background-color: rgba(0, 0, 0, 0.1);
  37.  
    }
  38.  
    .menu-item:hover {
  39.  
    background-color: rgba(0, 0, 0, 0.4);
  40.  
    }
  41.  
    .menu-item:hover .menu-content {
  42.  
    display: block;
  43.  
    }
  44.  
    .menu-loading {
  45.  
    margin: 45px 0 0 92px;
  46.  
    }
  47.  
     
  48.  
    /* loading-page */
  49.  
    .loading-page {
  50.  
    position: absolute;
  51.  
    top: 0;
  52.  
    right: 0;
  53.  
    bottom: 0;
  54.  
    left: 0;
  55.  
    z-index: 1000;
  56.  
    background-color: #eee;
  57.  
    text-align: center;
  58.  
    }
  59.  
    .loading-img {
  60.  
    position: absolute;
  61.  
    top: 50%;
  62.  
    }
  63.  
    .ad img {
  64.  
    display: inline-block;
  65.  
    width: 25%;
  66.  
    }
  67.  
    .none {
  68.  
    display: none;
  69.  
    }
  70.  
    </style>
  71.  
    </head>
  72.  
    <body>
  73.  
    <div id="loading-page" class="loading-page">
  74.  
    <img class="loading-img" src="https://blog.csdn.net/zhiqinzhe/article/details/loading.gif" alt="加载中" />
  75.  
    </div>
  76.  
     
  77.  
    <div id="ad" class="ad"></div>
  78.  
     
  79.  
    <ul id="menu" class="menu">
  80.  
    <!-- <li class="menu-item" data-key="hot" data-done="done">
  81.  
    <span>热门</span>
  82.  
    <div class="menu-content">
  83.  
    <p><img class="menu-loading" src="https://blog.csdn.net/zhiqinzhe/article/details/loading.gif" alt="加载中" /></p>
  84.  
    </div>
  85.  
    </li> -->
  86.  
    </ul>
  87.  
    <script type="module">
  88.  
    import { getJSON } from './ajax/index.js';
  89.  
     
  90.  
    const menuURL = 'https://www.imooc.com/api/mall-PC/index/menu';
  91.  
    const adURL = 'https://www.imooc.com/api/mall-PC/index/ad';
  92.  
     
  93.  
    const loadingPageEl = document.getElementById('loading-page');
  94.  
    const adEl = document.getElementById('ad');
  95.  
    const menuEl = document.getElementById('menu');
  96.  
     
  97.  
    const p1 = getJSON(menuURL)
  98.  
    .then(repsonse => {
  99.  
    // console.log(repsonse);
  100.  
     
  101.  
    let html = '';
  102.  
     
  103.  
    for (const item of repsonse.data) {
  104.  
    html = `
  105.  
    <li class="menu-item" data-key="${item.key}">
  106.  
    <span>${item.title}</span>
  107.  
    <div class="menu-content">
  108.  
    <p><img class="menu-loading" src="https://blog.csdn.net/zhiqinzhe/article/details/loading.gif" alt="加载中" /></p>
  109.  
    </div>
  110.  
    </li>
  111.  
    `;
  112.  
    }
  113.  
     
  114.  
    menuEl.innerHTML = html;
  115.  
     
  116.  
    // [{key: "hot", title: "热门出发地", subTitles: Array(5)}]
  117.  
     
  118.  
    // ...
  119.  
    })
  120.  
    .then(() => {
  121.  
    const items = menuEl.querySelectorAll('.menu-item');
  122.  
     
  123.  
    for (const item of items) {
  124.  
    item.addEventListener(
  125.  
    'mouseenter',
  126.  
    () => {
  127.  
    // console.log(item.getAttribute('data-key'));
  128.  
     
  129.  
    // IE11 开始支持
  130.  
    // console.log(item.dataset.key);
  131.  
     
  132.  
    if (item.dataset.done === 'done') return;
  133.  
     
  134.  
    getJSON(
  135.  
    `https://www.imooc.com/api/mall-PC/index/menu/${item.dataset.key}`
  136.  
    )
  137.  
    .then(repsonse => {
  138.  
    // console.log(repsonse);
  139.  
     
  140.  
    // [{title: "内地热门城市", cities: Array(27)}]
  141.  
     
  142.  
    item.dataset.done = 'done';
  143.  
     
  144.  
    let html = '';
  145.  
     
  146.  
    for (const item of repsonse.data) {
  147.  
    html = `<p>${item.title}</p>`;
  148.  
    }
  149.  
     
  150.  
    item.querySelector('.menu-content').innerHTML = html;
  151.  
    })
  152.  
    .catch(err => {
  153.  
    console.log(err);
  154.  
    });
  155.  
    },
  156.  
    false
  157.  
    );
  158.  
    }
  159.  
    })
  160.  
    .catch(err => {
  161.  
    console.log(err);
  162.  
    });
  163.  
     
  164.  
    const p2 = getJSON(adURL)
  165.  
    .then(response => {
  166.  
    // console.log(response);
  167.  
    // [{ url: 'http://alimc.img.imooc.com/class/' }];
  168.  
     
  169.  
    let html = '';
  170.  
    for (const item of response.data) {
  171.  
    html = `<img src="https://blog.csdn.net/zhiqinzhe/article/details/${item.url}" alt="" />`;
  172.  
    }
  173.  
    adEl.innerHTML = html;
  174.  
    })
  175.  
    .catch(err => {
  176.  
    console.log(err);
  177.  
    });
  178.  
     
  179.  
    Promise.all([p1, p2]).then(() => {
  180.  
    // loadingPageEl.style.display = 'none';
  181.  
     
  182.  
    // IE10 开始支持
  183.  
    loadingPageEl.classList.add('none');
  184.  
    // loadingPageEl.classList.remove('none');
  185.  
    });
  186.  
    </script>
  187.  
    </body>
  188.  
    </html>
  1.  
    // 1.axios 是什么
  2.  
    // axios 是一个基于 Promise 的 HTTP 库,可以用在浏览器和 node.js 中
  3.  
    // 第三方 Ajax 库
  4.  
     
  5.  
    // http://www.axios-js.com/zh-cn/docs/
  6.  
     
  7.  
    // 2.axios 的基本用法
  8.  
    // 引入 axios
  9.  
    // console.log(axios);
  10.  
     
  11.  
    const url = 'https://www.imooc.com/api/http/search/suggest?words=js';
  12.  
    // axios(url, {
  13.  
    // method: 'post',
  14.  
     
  15.  
    // // 请求时的头信息
  16.  
    // headers: {
  17.  
    // 'Content-Type': 'application/x-www-form-urlencoded'
  18.  
    // // 'Content-Type': 'application/json'
  19.  
    // },
  20.  
     
  21.  
    // // 通过请求头携带的数据
  22.  
    // params: {
  23.  
    // username: 'alex'
  24.  
    // },
  25.  
     
  26.  
    // // 通过请求体携带的数据
  27.  
     
  28.  
    // // application/json
  29.  
    // // data: {
  30.  
    // // age: 18,
  31.  
    // // sex: 'male'
  32.  
    // // }
  33.  
     
  34.  
    // // application/x-www-form-urlencoded
  35.  
    // data: 'age=18&sex=male'
  36.  
     
  37.  
    // // timeout: 10
  38.  
     
  39.  
    // // withCredentials: true
  40.  
    // })
  41.  
    // .then(response => {
  42.  
    // console.log(response);
  43.  
    // console.log(response.data.data);
  44.  
    // })
  45.  
    // .catch(err => {
  46.  
    // console.log(err);
  47.  
    // });
  48.  
     
  49.  
    // axios
  50.  
    // .get(url, {
  51.  
    // params: {
  52.  
    // username: 'alex'
  53.  
    // }
  54.  
    // })
  55.  
    // .then(response => {
  56.  
    // console.log(response);
  57.  
    // });
  58.  
     
  59.  
    // axios
  60.  
    // .post(url, 'username=alex&age=18')
  61.  
    // .then(response => {
  62.  
    // console.log(response);
  63.  
    // })
  64.  
    // .catch(err => {
  65.  
    // console.log(err);
  66.  
    // });
  67.  
     
  68.  
    axios
  69.  
    .post('https://www.imooc.com/api/http/json/search/suggest?words=js', {
  70.  
    username: 'alex'
  71.  
    })
  72.  
    .then(response => {
  73.  
    console.log(response);
  74.  
    })
  75.  
    .catch(err => {
  76.  
    console.log(err);
  77.  
    });
  78.  
     
  79.  
    // axios.put()
  80.  
    // axios.delete()
  1.  
    // 1.Fetch 是什么
  2.  
    // Fetch 也是前后端通信的一种方式
  3.  
    // Fetch 是 Ajax(XMLHttpRequest)的一种替代方案,它是基于 Promise 的
  4.  
     
  5.  
    // Ajax 的兼容性比 Fetch 好
  6.  
     
  7.  
    // abort timeout
  8.  
     
  9.  
    // 2.Fetch 的基本用法
  10.  
    // console.log(fetch);
  11.  
    // console.log(ajax);
  12.  
     
  13.  
    // fetch() 调用后返回 Promise 对象
  14.  
    const url = 'https://www.imooc.com/api/http/search/suggest?words=js';
  15.  
     
  16.  
    // body: (...)
  17.  
    // bodyUsed: false
  18.  
    // ok: true
  19.  
    // status: 200
  20.  
    // statusText: "OK"
  21.  
    // type: "cors"
  22.  
    // url: "https://www.im
  23.  
     
  24.  
    // 第二个参数是对象,用来配置 fetch
  25.  
    const fd = new FormData();
  26.  
    fd.append('username', 'alex');
  27.  
    fetch(url, {
  28.  
    method: 'post',
  29.  
    // body: null
  30.  
    // body: 'username=alex&age=18',
  31.  
    // body: JSON.stringify({ username: 'alex' })
  32.  
    body: fd,
  33.  
    // headers: {
  34.  
    // // 'Content-Type': 'application/x-www-form-urlencoded'
  35.  
    // 'Content-Type': 'application/json'
  36.  
    // }
  37.  
    mode: 'cors'
  38.  
    // credentials:'include'
  39.  
    })
  40.  
    .then(response => {
  41.  
    console.log(response);
  42.  
     
  43.  
    // body/bodyUsed
  44.  
    // body 只能读一次,读过之后就不让再读了
  45.  
     
  46.  
    // ok
  47.  
    // 如果为 true,表示可以读取数据,不用再去判断 HTTP 状态码了
  48.  
     
  49.  
    if (response.ok) {
  50.  
    // console.log(response.json());
  51.  
     
  52.  
    return response.json();
  53.  
    // return response.text();
  54.  
    } else {
  55.  
    throw new Error(`HTTP CODE 异常 ${response.status}`);
  56.  
    }
  57.  
    })
  58.  
    .then(data => {
  59.  
    console.log(data);
  60.  
    })
  61.  
    .catch(err => {
  62.  
    console.log(err);
  63.  
    });

本篇文章来至:学新通

  • 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
  • 本站站名: 学新通
  • 本文地址: https://www.swvq.com/boutique/detail/tanhckejfk
  • 联系方式: luke.wu#vfv.cc
系列文章
更多 icon
同类精品
更多 icon
我要评论
我的头像
精彩评论
继续加载