AJAX基础
一、什么是AJAX? [async javascript and xml(json)]
- 异步的js和xml:实现数据请求 + 客户端渲染 =>局部刷新
- 这里的异步不是JavaScript异步编程(eventloop/eventqueue)
- 同步刷新(服务器渲染,整个页面都要刷新)
- 异步刷新(JS操控的客户端刷新,可以局部刷新)
- 由于速度快,体验更好,开始流行前后端分离
- 底层核心:XMLHttpRequest API
- XHR对象用于与服务器交互,通过 XMLHttpRequest 可以在不刷新页面的情况下请求特定 URL,获取数据。这允许网页在不影响用户操作的情况下,更新页面的局部内容
- XML[可扩展标记语言] => JSON (xml已经很少用了)
二、AJAX的基础操作
大致流程:
- 创建XMLHTTPRequest对象 var xhr = new XMLHttpRequest()
- 创建一个新的http请求
- 包括:请求的方法、请求的url
- xhr.open(“get”, url, true) //true为异步,false同步
- 发送HTTP请求
- 设置响应HTTP请求状态变化的函数
- 获取异步调用返回的数据
- 利用JS操作DOM实现局部刷新
- 创建XHR(ActiveXObject)
- let xhr = new XMLHttpRequest;
- 打开一个URL地址「发送请求前的一些配置信息」
- method 请求方式:
GET和POST在官方定义中是没有明确的区别的,但是浏览器或者开发的时候,都有一套约定俗成的规范,其实只有参数格式有区别:
1. **GET**(get/delete/head/options...)
1. GET请求传递给服务器的信息,除了请求头传递以外,要求基于URL问号传参传递给服务器
1. xhr.open('GET', './1.json?lx=1&name=xxx')
2. **POST**(post/put/patch...)
1. POST请求要求传递给服务器的信息,是基于请求主体传递
1. xhr.send('lx=1&name=xxx')
3. 由于**格式导致的区别**:
1. **信息传递**
1. **GET **传递的信息不如POST多,因为URL有长度限制「IE->2KB」,超过这个长度的信息会被自动截掉,这样导致传递内容过多,最后服务器收到的信息是不完整的!!
1. **POST **理论上是没有限制的,但是传递的东西越多,速度越慢,可能导致浏览器报传输超时的错误,所以实际上我们会自己手动做限制!!
2. **缓存**
1. **GET **会产生缓存「浏览器默认产生的,**不可控的缓存**」:两次及以上,请求相同的API接口,并且传递的参数也一样,浏览器可能会把第一次请求的信息直接返回,而不是从服务器获取最新的信息!!
1. 在请求URL的**末尾设置随机数**,以此来**清除**GET缓存的副作用
1. xhr.open('GET', './1.json?lx=1&name=xxx&_'+Math.random())
3. **安全性**
1. GET传递的**信息是基于URL末尾拼接**,这个随便做一些劫持或者修改,都可以直接改了
1. POST相对于GET来讲更安全一些:POST请求主体信息的劫持,没那么好做!!但是“互联网面前,人人都在裸奔”!!所以不管什么方式,只要涉及安全的信息,都需要**手动加密**「因为默认所有的信息传输都是明文的」!!
4. **tcp/ip层区别**
1. get 会产生一个 tcp 数据包
1. 浏览器会把headers 和 data 一起发送出去,服务器响应 200(返回数据)
2. post 会产生两个 tcp 数据包
1. 浏览器先发送headers,服务器响应 100 continue
1. 浏览器再发送 data,服务器响应 200(返回数据)
- url 请求的URL地址
- async 是否采用异步 [默认是TRUE]
- username
- userpass
- 监听状态和获取数据
- ajax状态 xhr.readyState
- 0 =>UNSENT 未发送
- 1 =>OPENED 打开一个url地址后(服务器连接已建立)
- 2 =>HEADERS_RECEIVED 响应头信息已经返回
- 3 =>LOADING 响应主体信息正在处理
- 4 =>DONE 响应主体信息已经返回
HTTP状态码 +HTTP状态码描述 xhr.status/xhr.statusText | HTTP状态码 | HTTP状态码描述 | 中文描述 | | —- | —- | —- | | 200 | OK |
| | 202 | Accepted | 服务器已接受请求,但尚未处理(异步) | | 204 | No Content | 服务器成功处理了请求,但不需要返回任何实体内容(head请求) | | 301 | Moved Permanently | 永久转移 「域名迁移」 | | 302 | Move Temporarily | 临时转移 「负载均衡」 | | 304 | Not Modified | 缓存 | | 305 | Use Proxy | 代理 | | 400 | Bad Request | 请求参数有误 | | 401 | Unauthorized | 权限(Authorization) | | 403 | Forbidden | 服务器拒绝执行「为啥可能会已响应主体返回」情况很复杂,后端最好不要返回这玩意 | | 404 | Not Found | 地址错误 | | 405 | Method Not Allowed | 请求方式不被允许 | | 408 | Request Timeout | 请求超时 | | 500 | Internal Server Error | 未知服务器错误 | | 503 | Service Unavailable | 超负荷 | | 505 | HTTP Version Not Supported |
| |
|
|
|
- 获取响应主体信息 xhr.response/responseText/responseXML…
- 服务器返回的响应主体信息的格式 responseText
- XML格式数据 responseXML
- 文件流格式数据「buffer/二进制…」
获取响应头信息 xhr.getResponseHeader/getAllResponseHeaders
发送请求「send中传递的信息,就是设置的请求主体信息」 (必会)基于请求主体传递给服务器的数据格式是有要求的「Postman接口测试工具」
- postman:
1,form-data 主要应用于文件的上传或者表单数据提交
// 设置请求头
xhr.setRequestHeader('Content-Type', 'multipart/form-data');
------
let fd = new FormData;
fd.append('lx', 0);
fd.append('name', 'xxx');
xhr.send(fd);
** 2.**`**x-www-form-urlencoded**` 格式的字符串
1. Qs.stringify/parse: 实现 对象 和 urlencoded格式字符串之间的转换
// 格式:“lx=1&name=xxx” 「常用」
// Qs库:$npm i qs
// 设置请求头
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
------
xhr.send(Qs.stringify({
lx: 0,
name: 'xxx'
}));
// Qs.stringify/parse: 实现 对象 和 urlencoded格式字符串之间的转换
// Qs.stringify({lx: 0, name: 'xxx'}) => "lx=0&name=xxx"
// Qs.parse("lx=0&name=xxx") => {lx: 0, name: 'xxx'}
3,**raw**
字符串格式 JSON字符串 => JSON.stringify/parse 「常用」
// 1. 普通字符串
xhr.setRequestHeader('Content-Type', 'text/plain')
// 2. JSON字符串 => JSON.stringify/parse 「常用」
xhr.setRequestHeader('Content-Type', 'application/json')
// 3. XML格式字符串
xhr.setRequestHeader('Content-Type', ' application/xml')
4,binary进制数据文件「buffer/二进制…」
一般也应用于文件上传
图片 -> image/jpeg
EXCEL -> application/vnd.openxmlformats-officedocument.spreadsheetml.sheet
汇总XHR的属性和方法及事件
- xhr.response / xhr.responseText / xhr.responseXML
- xhr.status / xhr.statusText
- xhr.timeout
- xhr.withCredentials
- xhr.abort()
- xhr.getAllResponseHeaders()
- xhr.getResponseHeader([key])
- xhr.open()
- xhr.overrideMimeType()
- xhr.send()
- xhr.setRequestHeader()