XHR 理解和使用
使用 XMLHttpRequest(XHR) 对象可以与服务器交互, 也就是发送 Ajax 请求
前端可以获取到数据, 而无需让整个的页面刷新.
这使得 web 可以只更新页面的局部, 而不影响用户的操作
区别一般 http 请求与 Ajax 请求
Ajax 请求是一种特别的 http 请求
对服务器来说, 没有任何区别, 区别在浏览器端
浏览器端发送请求: 只有 XHR 或 fetch 发出的才是 Ajax 请求, 其他的都是非 Ajax 请求
浏览器端接收到响应
一般请求: 浏览器一般会直接显示响应体数据, 也就是我们常说的刷新 / 跳转页面
Ajax 请求: 浏览器不会对界面进行任何更新操作, 只是调用监视的回调函数并传入响应相关数据
API
XMLHttpRequest(): 创建 XHR 对象的构造函数
status: 响应状态码值, 比如 2000,404
statusText: 响应状态文本
readyState: 标识请求状态的只读属性
0: 初始
1: open() 之后
2: send() 之后
3: 请求中
4: 请求完成
onreadystatechange: 绑定 readyState 给变的监听
responseType: 指定响应数据类型, 如果是'json', 得到响应后自动解析响应体数据
response: 响应体数据, 类型取决于 responseType 的指定
timeout: 指定请求超时时间, 默认为 0 代表没有限制
ontimeout: 绑定超时的监听
onerror: 绑定请求网络错误的监听
open(): 初始化一个请求, 参数为: (method, url[, async])
send(data): 发送请求
abort(): 中断请求
getResponseHeader(name): 获取指定名称的响应头值
getAllResponseHeaders(): 获取所有响应头组成的字符串
setRequestHeader(name, value): 设置请求头
XHR 的 Ajax 封装 (简单版 axios)
特点
函数的返回值为 promise, 成功的结果为 response, 异常的结果为 error
能处理多种类型的请求: GET/POST/PUT/DELETE
函数的参数为一个配置对象
- {
- url: '', // 请求地址
- method: '', // 请求方式 GET/POST/PUT/DELETE
- params: {
- }, // GET/DELETE 请求的 query 参数
- data: {
- }, // POST 或 DELETE 请求的请求体参数
- }
响应 JSON 数据自动解析为 JS
编码实现
- lang="en">
- charset="UTF-8">
- name="viewport" content="width=device-width, initial-scale=1.0">
- http-equiv="X-UA-Compatible" content="ie=edge">
使用 XHR 封装 Ajax 请求参数
onclick="testGet()">
发送 GET 请求
onclick="testPost()">
发送 POST 请求
onclick="testPut()">
发送 PUT 请求
onclick="testDelete()">
发送 Delete 请求
- /* 1. GET 请求: 从服务器端获取数据 */
- function testGet() {
- axios({
- // url: 'http://localhost:3000/posts',
- url: 'http://localhost:3000/posts2',
- method: 'GET',
- params: {
- id: 1,
- xxx: 'abc'
- }
- }).then(response =>{
- console.log(response)
- },
- error =>{
- alert(error.message)
- })
- }
- /* 2. POST 请求: 服务器端保存数据 */
- function testPost() {
- axios({
- url: 'http://localhost:3000/posts',
- method: 'POST',
- data: {
- "title": "json-server---",
- "author": "typicode---"
- }
- }).then(response =>{
- console.log(response)
- },
- error =>{
- alert(error.message)
- })
- }
- /* 3. PUT 请求: 服务器端更新数据 */
- function testPut() {
- axios({
- url: 'http://localhost:3000/posts/1',
- method: 'put',
- data: {
- "title": "json-server+++",
- "author": "typicode+++"
- }
- }).then(response =>{
- console.log(response)
- },
- error =>{
- alert(error.message)
- })
- }
- /* 2. DELETE 请求: 服务器端删除数据 */
- function testDelete() {
- axios({
- url: 'http://localhost:3000/posts/2',
- method: 'delete'
- }).then(response =>{
- console.log(response)
- },
- error =>{
- alert(error.message)
- })
- }
- /*
- 1. 函数的返回值为 promise, 成功的结果为 response, 失败的结果为 error
- 2. 能处理多种类型的请求: GET/POST/PUT/DELETE
- 3. 函数的参数为一个配置对象
- {
- url: '', // 请求地址
- method: '', // 请求方式 GET/POST/PUT/DELETE
- params: {}, // GET/DELETE 请求的 query 参数
- data: {}, // POST 或 DELETE 请求的请求体参数
- }
- 4. 响应 JSON 数据自动解析为 JS 的对象 / 数组
- */
- function axios({
- url,
- method = 'GET',
- params = {},
- data = {}
- }) {
- // 返回一个 promise 对象
- return new Promise((resolve, reject) =>{
- // 处理 method(转大写)
- method = method.toUpperCase()
- // 处理 query 参数 (拼接到 url 上) id=1&xxx=abc
- /*
- {
- id: 1,
- xxx: 'abc'
- }
- */
- let queryString = ''Object.keys(params).forEach(key =>{
- queryString += `$ {
- key
- } = $ {
- params[key]
- } & `
- }) if (queryString) { // id=1&xxx=abc&
- // 去除最后的 &
- queryString = queryString.substring(0, queryString.length - 1)
- // 接到 url
- url += '?' + queryString
- }
- // 1. 执行异步 Ajax 请求
- // 创建 xhr 对象
- const request = new XMLHttpRequest()
- // 打开连接 (初始化请求, 没有请求)
- request.open(method, url, true)
- // 发送请求
- if (method === 'GET' || method === 'DELETE') {
- request.send()
- } else if (method === 'POST' || method === 'PUT') {
- request.setRequestHeader('Content-Type', 'application/json;charset=utf-8') // 告诉服务器请求体的格式是 JSON
- request.send(JSON.stringify(data)) // 发送 JSON 格式请求体参数
- }
- // 绑定状态改变的监听
- request.onreadystatechange = function() {
- // 如果请求没有完成, 直接结束
- if (request.readyState !== 4) {
- return
- }
- // 如果响应状态码在 [200, 300) 之间代表成功, 否则失败
- const {
- status,
- statusText
- } = request
- // 2.1. 如果请求成功了, 调用 resolve()
- if (status>= 200 && status <= 299) {
- // 准备结果数据对象 response
- const response = {
- data: JSON.parse(request.response),
- status,
- statusText
- }
- resolve(response)
- } else { // 2.2. 如果请求失败了, 调用 reject()
- reject(new Error('request error status is' + status))
- }
- }
- })
- }
来源: http://www.bubuko.com/infodetail-3653738.html