前后端通信方式之Ajax、Fetch

Ajax

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

需要搭建服务器环境;因非服务器环境下,很多浏览器无法正常使用 Ajax
比如:
Live Server
windows phpStudy
Mac MAMP
XMLHttpRequest

兼容性比 Fetch 好

使用步骤

1.创建 xhr 对象

   const xhr = new XMLHttpRequest();

2.监听事件,处理响应

会触发readystatechange 事件;在该事件中处理响应

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

status属性
200-299成功;
304 Not Modified,文件未过期,能用

readyState

readystatechange 监听 readyState 的状态变化
共 5 个状态
0:未初始化。未调用 open()
1:启动。已调用 open(),但未调用 send()
2:发送。已调用 send(),但未接收到响应
3:接收。接收到部分响应数据
4:完成。接收到全部响应数据,且可在浏览器中使用

3.准备发送请求

向远程/本地
调用 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:异步

4.正式发送请求

调用 send()

xhr.send(null);

通过请求体携带的数据
1)open()中使用get请求不会报错,但不会发送数据
GET请求头携带数据

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

2)open()中要使用post请求才会成功发送数据
POST请求头/请求体携带数据

xhr.open('POST', url, true);
xhr.send('username=alex&age=18');

对象会被转换成字符串

xhr.send({
  username: 'alex',
  age: 18
});
//[object Object]

封装Ajax

利用模块系统、类进行封装
用Promise改造
失败的4种方法:分别调用reject(),通过传入参数区分

FormData-用 Ajax 提交表单

直接提交会跳转网页,不希望跳转时可使用Ajax提交表单
思路:登录按钮绑定点击事件,获取用户名、密码的数据值,将其组装成常用格式,使用ajax发送
HTML 表单元素创建 FormData 对象

const fd = new FormData(表单元素);
xhr.send(fd);
append() 方法添加数据
const fd = new FormData(表单元素);
fd.append('age', 18);
fd.append('sex', 'male');
xhr.send(fd);

IE10 及以上可支持

<form
id="login"
action="https://www.imooc.com/api/http/search/suggest?words=js"
method="POST"
enctype="multipart/form-data"
>
<input type="text" name="username" placeholder="用户名" />
<input type="password" name="password" placeholder="密码" />
<input id="submit" type="submit" value="登录" />
</form>
const login = document.getElementById('login');
// console.log(login.username);
// console.log(login.password);
//解构赋值,获取username password 的数据值
const { username, password } = login;
const btn = document.getElementById('submit');
const url = 'https://www.imooc.com/api/http/search/suggest?words=js';
btn.addEventListener(
'click',
e => {
// 阻止表单自动提交
e.preventDefault();
// 表单数据验证
//…
// 发送 Ajax 请求
const xhr = new XMLHttpRequest();
xhr.addEventListener(
'load',
() => {
if (
(xhr.status >= 200 && xhr.status < 300) ||
xhr.status === 304
) {
console.log(xhr.response);
}
},
false
);
xhr.open('POST', url, true);
// 组装数据
// const data = `username=${username.value}&password=${password.value}`;
// FormData 可用于发送表单数据
const data = new FormData(login);
// data.append('age', 18); 
// data.append('sex', 'male');
// console.log(data);
// for (const item of data) {
//   console.log(item);
// }
// xhr.setRequestHeader(
//   'Content-Type',
//   'application/x-www-form-urlencoded'
// );
xhr.send(data);
// xhr.send('username=alex&password=12345');
},
false
);

axios-基于 Promise 的 HTTP 库

<!-- <script src="https://unpkg.com/axios/dist/axios.min.js"></script> -->
<script src="https://unpkg.com/axios@0.19.2/dist/axios.min.js"></script>
<script>
可以用在浏览器和 node.js 中
第三方 Ajax 库
// http://www.axios-js.com/zh-cn/docs/
用法
// 引入 axios
// console.log(axios);
const url = 'https://www.imooc.com/api/http/search/suggest?words=js';
// axios(url, {
//   method: 'post',
//   // 请求时的头信息
//   headers: {
//     'Content-Type': 'application/x-www-form-urlencoded'
//     // 'Content-Type': 'application/json'
//   },
//   // 通过请求头携带的数据
//   params: {
//     username: 'alex'
//   },
//   // 通过请求体携带的数据
//   // application/json
//   // data: {
//   //   age: 18,
//   //   sex: 'male'
//   // }
//   // application/x-www-form-urlencoded
//   data: 'age=18&sex=male'
//   // timeout: 10
//   // withCredentials: true
// })
//   .then(response => {
//     console.log(response);
//     console.log(response.data.data);
//   })
//   .catch(err => {
//     console.log(err);
//   });
// axios
//   .get(url, {
//     params: {
//       username: 'alex'
//     }
//   })
//   .then(response => {
//     console.log(response);
//   });
// axios
//   .post(url, 'username=alex&age=18')
//   .then(response => {
//     console.log(response);
//   })
//   .catch(err => {
//     console.log(err);
//   });
axios
.post('https://www.imooc.com/api/http/json/search/suggest?words=js', {
username: 'alex'
})
.then(response => {
console.log(response);
})
.catch(err => {
console.log(err);
});
// axios.put()
// axios.delete()

应用-完成前后端通信

功能:在不重新加载整个页面的情况下,对页面的某部分进行更新
① 慕课网注册检测-手机号是否已存在
② 慕课网搜索提示-输入关键字从后端传来提示词条

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); 

数据交换格式

XML

Extensible Markup Language可扩展标记语言
已渐渐被JSON取代

JSON

JavaScript Object Notation ,JS 对象简谱
是前后端数据的中转格式
JS->JSON->PHP/Java
PHP/Java->JSON->JS

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);
        }
      };
xhr.open('GET', url, true);
xhr.send(null);
//输出JSON格式
//{"code":200,"data":[{"word":"jsp"},{"word":"js"},{"word":"json"},{"word":"js \u5165\u95e8"},{"word":"jstl"}]}

3 种形式

3 种形式和 JS 中的数据类型很像

简单值形式-对应 JS 的基础数据类型

.json文件
① JSON中无有 undefined 值
② JSON中的字符串必须使用双引号
③ JSON不能注释

对象形式-对应 JS 的对象

属性名必须用双引号
属性值若是字符串也必须用双引号
不支持 undefined

{
  "name": "张三",
  "age": 18,
  "hobby": ["足球", "乒乓球"],
  "family": {
    "father": "张老大",
    "mother": "李四"
  }
}
数组形式-对应 JS 的数组

数组中的字符串必须用双引号
不支持 undefined

[1, "hi", null]
[
  {
    "id": 1,
    "username": "张三",
    "comment": "666"
  },
  {
    "id": 2,
    "username": "李四",
    "comment": "999 6翻了"
  }
]
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', './plain.json', true);
// xhr.open('GET', './obj.json', true);
xhr.open('GET', './arr.json', true);
xhr.send(null);

方法

JSON.parse()-解析字符串-JSON到JS

将 JSON 格式的字符串解析成 JS 中的对应值
得是合法的 JSON 字符串,否则会报错

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);
          console.log(JSON.parse(xhr.responseText));
          // console.log(JSON.parse(xhr.responseText).data);
      }
};
// xhr.open('GET', './plain.json', true);
// xhr.open('GET', './obj.json', true);
xhr.open('GET', './arr.json', true);
// xhr.open(
//   'GET',
//   'https://www.imooc.com/api/http/search/suggest?words=js',
//   true
// );
xhr.send(null);
JSON.stringify()-解析基本数据类型、对象、数组-JS到JSON

将 JS 的基本数据类型、对象或数组转换成 JSON 格式的字符串

console.log(
  JSON.stringify({
    username: 'alex',
    age: 18
  })
);
const xhr = new XMLHttpRequest();
xhr.open(
  'POST',
  'https://www.imooc.com/api/http/search/suggest?words=js',
  true
);
xhr.send(
  JSON.stringify({
    username: 'alex',
    age: 18
  })
);

应用-封装 localStorage

import { get, set, remove, clear } from './storage.js';
set('username', 'alex');
console.log(get('username'));
set('zs', {
  name: '张三',
  age: 18
});
console.log(get('zs'));
remove('username');
clear();

Fetch

是 Ajax(XMLHttpRequest)的一种替代方案
是基于 Promise 的
未提供abort timeout等方式
调用后返回 Promise 对象

用法

console.log(fetch);
console.log(ajax);
const url = 'https://www.imooc.com/api/http/search/suggest?words=js';
// body: (...)
// bodyUsed: false
// ok: true
// status: 200
// statusText: "OK"
// type: "cors"
// url: "https://www.im

第二个参数是对象,用来配置 fetch

const fd = new FormData();
fd.append('username', 'alex');
fetch(url, {
method: 'post',
// body: null
// body: 'username=alex&age=18',
// body: JSON.stringify({ username: 'alex' })
body: fd,
// headers: {
//   // 'Content-Type': 'application/x-www-form-urlencoded'
//   'Content-Type': 'application/json'
// }
mode: 'cors'
// credentials:'include'
})
.then(response => {
console.log(response);
// body/bodyUsed
// body 只能读一次,读过之后就不让再读了
// ok
// 如果为 true,表示可以读取数据,不用再去判断 HTTP 状态码了
if (response.ok) {
// console.log(response.json());
return response.json();
// return response.text();
} else {
throw new Error(`HTTP CODE 异常 ${response.status}`);
}
})
.then(data => {
console.log(data);
})
.catch(err => {
console.log(err);
});

附加:XMLHttpRequest

是一组API函数集,可被JavaScript、JScript、VBScript以及其它web浏览器内嵌的脚本语言调用
通过HTTP在浏览器和web服务器之间收发XML或其它数据。
可以动态地更新网页,它无需重新从服务器读取整个网页,也不需要安装额外的插件
除XML之外,XMLHTTP还能用于获取其它格式的数据,如JSON或者甚至纯文本

属性

responseType

响应类型:空/text/json
默认值:空/text
与 responseText关系
1)若未设置responseType,或值为 ‘空/text’
则与 responseText属性作用同
2)若responseType = ‘JSON’
responseText无法使用

responseText

响应数据的文本格式

response

响应数据

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('responseText:', xhr.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);

IE6~9 不支持,IE10 开始支持

timeout

请求的超时时间(单位 ms)
配合timeout事件


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);

IE6~7 不支持,IE8 开始支持

withCredentials

指定是否携带 Cookie
同域时,默认携带 Cookie;
跨域时,不携带 Cookie,想携带需设置xhr.withCredentials = true;
跨域携带 Cookie能否成功,还需看服务器安全策略是否拦截
和后端沟通,设置指定域名的跨域请求,例如Access-Control-Allow-Origin:

http://127.0.0.1:5500
 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);

IE6~9 不支持,IE10 开始支持

方法

abort()

终止当前请求
配合 abort 事件一起使用
发送完请求后调用

 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.send(null);
  xhr.abort();

setRequestHeader()

设置请求头信息
Content-Type 字段-告诉服务器,浏览器发送的数据是什么格式的

 // const url = 'https://www.imooc.com/api/http/search/suggest?words=js';
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);
// 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'
  })
);

事件

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);

IE6~8 不支持 load 事件

error -请求发生错误时触发

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);

IE10 开始支持

abort -终止请求时触发

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();

IE10 开始支持

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);

// IE8 开始支持

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值