AJAX基础

1 AJAX简介

Ajax = Asynchronous Javascript And XML,即异步JavaScript和XML,它最大的特点就是能够在网页不刷新的情况下向服务端发送HTTP请求,然后得到HTTP响应。AJAX不是新的编程语言,而是一种将现有的标准组合在一起使用的新方式。

1.1 AJAX的优点

  • 可以无需刷新页面与服务器进行交互
  • 运行根据用户事件来更新部分页面内容

1.2 AJAX的缺点

  • 没有浏览历史,不能回退
  • 存在跨域问题
  • SEO问题

2 XML简介

之所以在AJAX中提到XML是因为最初AJAX在进行数据交换的时候就是使用XML格式的数据(服务端给客户端返回的数据就是XML格式的,客户端再解析XML得到数据),XML 指可扩展标记语言(eXtensible Markup Language),XML 被设计用来传输和存储数据,如:

<?xml version="1.0" encoding="UTF-8"?>
<note>
  <to>Tove</to>
  <from>Jani</from>
  <heading>Reminder</heading>
  <body>Don't forget me this weekend!</body>
</note>

可以看到XML和HTML类似,不同的是HTML中都是预定义标签,而XML中没有预定义标签,全部都是自定义标签。
不过现在进行AJAX操作时,不再使用XML了,都是使用JSON格式了,这种数据格式更加灵活方便。

3 JSON简介

JSON = JavaScript Object Notation,即JavaScript 对象表示法,JSON 是存储和交换文本信息的语法,类似 XML。JSON 比 XML 更小、更快,更易解析,如:

{
    "sites": [
      { "name":"百度" , "url":"www.baidu.com" }, 
      { "name":"谷歌" , "url":"www.google.com" }, 
    ]
}

4 HTTP协议请求报文与响应报文的格式

HTTP = HyperText Transfer Protocol,即超文本传输协议,协议详细规定了浏览器和万维网服务器之间互相通信的规则。

4.1 请求报文

一个HTTP请求报文由请求行(request line)、请求头部(header)、空行和请求数据4个部分组成,下图给出了请求报文的一般格式:
在这里插入图片描述

4.2 响应报文

HTTP响应报文由状态行、响应头部、空行 和 响应包体 4 个部分组成,如下图所示:
在这里插入图片描述

5 AJAX请求的基本操作

新建文件夹,输入命令:npm init --yes,初始化项目,输入npm i express安装Express框架,新建express.js,添加如下代码:

const express = require('express')
const app = express()
app.get('/msg', (request, response) => {
  // 设置响应头,允许跨域
  response.setHeader('Access-Control-Allow-Origin', '*')
  // 设置响应体
  response.send('ok')
})
app.listen(3000, () => {
  console.log('服务已启动,监听3000端口')
})

输入node express.js命令后即可启动服务(建议使用nodemon工具,输入命令nodemon express.js后可以实现热更新)。在页面中发送请求的代码如下:

function send() {
  const xhr = new XMLHttpRequest()
  xhr.open('GET', 'http://127.0.0.1:3000/msg')
  xhr.send()
  xhr.onreadystatechange = function() {
    // 服务端返回了所有结果
    if (xhr.readyState === 4) {
      // 响应成功,状态码首位为2时,代表请求成功
      if (xhr.status >= 200 && xhr.status < 300) {
        // 1.响应行
        console.log(xhr.status)
        // 2.响应状态字符串
        console.log(xhr.statusText)
        // 3.所有响应头
        console.log(xhr.getAllResponseHeaders())
        // 4.响应体
        console.log(xhr.response)
      }
    }
  }
}

控制台输出结果如下:

200
OK
content-length: 2
content-type: text/html; charset=utf-8
ok

6 AJAX设置请求参数

请求参数的添加方法可以在请求URL后面跟上“?”,再接上等式,如“?a=1”,若需要添加多个参数,则使用“&”分隔即可:

xhr.open('GET', 'http://127.0.0.1:3000/msg?a=1&b=2')

发送请求后,可以在Chrome浏览器的开发者调试工具“Network”中选择该请求,在右侧的“Headers”中看到“Query String Parameters”:
在这里插入图片描述

7 AJAX发送POST请求

express.js中添加处理POST请求的路由:

  const express = require('express')
  const app = express()
  app.get('/msg', (request, response) => {
    // 设置响应头,运行跨域
    response.setHeader('Access-Control-Allow-Origin', '*')
    // 设置响应体
    response.send('ok')
  })
+  app.post('/msg', (request, response) => {
+    response.setHeader('Access-Control-Allow-Origin', '*')
+    response.send('POST OK')
+  })
  app.listen(3000, () => {
    console.log('服务已启动,监听3000端口')
  })

页面中发送请求的代码如下:

const xhr = new XMLHttpRequest()
xhr.open('POST', 'http://127.0.0.1:3000/msg')
xhr.send()
xhr.onreadystatechange = function() {
  if (xhr.readyState === 4) {
    // 响应成功,状态码首位为2时,代表请求成功
    if (xhr.status >= 200 && xhr.status < 300) {
      console.log(xhr.response)
    }
  }
}

发送请求后输出:“POST OK”。另外,在发送POST请求时可以手动设置请求体,可以把请求体放在xhr.send()的参数中:

    function send() {
      const xhr = new XMLHttpRequest()
      xhr.open('POST', 'http://127.0.0.1:3000/msg')
+      xhr.send('a=1&b=2')
      xhr.onreadystatechange = function() {
        if (xhr.readyState === 4) {
          // 响应成功,状态码首位为2时,代表请求成功
          if (xhr.status >= 200 && xhr.status < 300) {
            console.log(xhr.response)
          }
        }
      }
    }

发送POST请求后,可以在开发者调试工具中看到:
在这里插入图片描述

8 AJAX中设置请求头信息

设置请求头的方法为setRequestHeader,它必须在opensend前,如:

    function send() {
      const xhr = new XMLHttpRequest()
      xhr.open('POST', 'http://127.0.0.1:3000/msg')
      // 设置请求头信息
+      xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded')
      xhr.send('a=1&b=2')
      xhr.onreadystatechange = function() {
        if (xhr.readyState === 4) {
          if (xhr.status >= 200 && xhr.status < 300) {
            console.log(xhr.response)
          }
        }
      }
    }

此外还可以自定义请求头,如:xhr.setRequestHeader('MyRequestHeader', 'test'),不过设置这种请求头后发送请求会触发安全机制。

9 服务端响应JSON数据

express.js中添加如下代码:

app.get('/json', (request, response) => {
  response.setHeader('Access-Control-Allow-Origin', '*')
  const jsonData = {
    name: 'syz'
  }
  // 对对象进行字符串转换
  let str = JSON.stringify(jsonData)
  // send只能发送字符串
  response.send(str)
})

发送请求的代码如下:

function send() {
  const xhr = new XMLHttpRequest()
  xhr.open('GET', 'http://127.0.0.1:3000/json')
  xhr.send()
  xhr.onreadystatechange = function() {
    if (xhr.readyState === 4) {
      if (xhr.status >= 200 && xhr.status < 300) {
        console.log(xhr.response)
      }
    }
  }
}

输出结果:{"name":"syz"},注意这里只是字符串的形式,客户端要对该数据进行处理,则需要将字符串转换为对象:

    function send() {
      const xhr = new XMLHttpRequest()
      xhr.open('GET', 'http://127.0.0.1:3000/json')
      xhr.send()
      xhr.onreadystatechange = function() {
        if (xhr.readyState === 4) {
          if (xhr.status >= 200 && xhr.status < 300) {
+          	 // 字符串转换为对象
+            let data = JSON.parse(xhr.response)
+            console.log(data)
          }
        }
      }
    }

这样输出的结果就为对象的形式。此外还有一种自动转换的方式,这种方式需要借助于XMLHttpRequest对象上的respnseType属性:

    function send() {
      const xhr = new XMLHttpRequest()
+      // 将响应类型设置为json
+      xhr.responseType = 'json'
      xhr.open('GET', 'http://127.0.0.1:3000/json')
      xhr.send()
      xhr.onreadystatechange = function() {
        if (xhr.readyState === 4) {
          if (xhr.status >= 200 && xhr.status < 300) {
            console.log(xhr.response)
          }
        }
      }
    }

这样输出的结果也是对象的形式,这种方式更加的方便。

10 AJAX请求超时与异常处理

修改express.js中的msg接口,将其设置为4秒后再返回结果:

app.post('/msg', (request, response) => {
  response.setHeader('Access-Control-Allow-Origin', '*')
  setTimeout(() => {
    response.send('POST OK')
  }, 4000);
})

页面中的访问方法如下:

function send() {
  const xhr = new XMLHttpRequest()
  // 超时设置,设置为2秒,若2秒后还没有得到结果,则请求取消
  xhr.timeout = 2000
  xhr.open('POST', 'http://127.0.0.1:3000/msg')
  xhr.send()
  xhr.onreadystatechange = function() {
    if (xhr.readyState === 4) {
      if (xhr.status >= 200 && xhr.status < 300) {
        console.log(xhr.response)
      }
    }
  }
}

发送请求后可以看到请求的状态在2秒后变为了canceled
在这里插入图片描述

还可以为超时设置回调函数,如:

    function send() {
      const xhr = new XMLHttpRequest()
      // 超时设置,设置为2秒,若2秒后还没有得到结果,则请求取消
      xhr.timeout = 2000
+      // 超时回调
+      xhr.ontimeout = function() {
+        console.log('请求超时,请稍后再试!')
+      }
      xhr.open('POST', 'http://127.0.0.1:3000/msg')
      xhr.send()
      xhr.onreadystatechange = function() {
        if (xhr.readyState === 4) {
          if (xhr.status >= 200 && xhr.status < 300) {
            console.log(xhr.response)
          }
        }
      }
    }

还可以设置网络异常的回调,如没有网络:

    function send() {
      const xhr = new XMLHttpRequest()
      // 超时设置,设置为2秒,若2秒后还没有得到结果,则请求取消
      xhr.timeout = 2000
      // 超时回调
      xhr.ontimeout = function() {
        console.log('请求超时,请稍后再试!')
      }
+      // 异常回调
+      xhr.onerror = function() {
+        console.log('网络异常,请检查网络连接是否正确!')
+      }
      xhr.open('POST', 'http://127.0.0.1:3000/msg')
      xhr.send()
      xhr.onreadystatechange = function() {
        if (xhr.readyState === 4) {
          if (xhr.status >= 200 && xhr.status < 300) {
            console.log(xhr.response)
          }
        }
      }
    }

11 AJAX取消请求

取消请求需要使用XMLHttpRequest上的abort方法:

+    let xhr = null

    function send() {
      xhr = new XMLHttpRequest()
      xhr.open('POST', 'http://127.0.0.1:3000/msg')
      xhr.send()
      xhr.onreadystatechange = function() {
        if (xhr.readyState === 4) {
          if (xhr.status >= 200 && xhr.status < 300) {
            console.log(xhr.response)
          }
        }
      }
    }

+    function cancelSend() {
+      xhr.abort()
+    }

12 AJAX处理重复请求

let xhr = null
// 标识变量,当前是否在发送AJAX请求
let isSending = false
function send() {
  // 如果已经发送了,则取消上一次的请求,创建一个新的请求
  if (isSending) {
    xhr.abort()
  }
  // 在发送请求
  isSending = true
  xhr = new XMLHttpRequest()
  xhr.open('POST', 'http://127.0.0.1:3000/msg')
  xhr.send()
  xhr.onreadystatechange = function() {
    if (xhr.readyState === 4) {
      // 发送请求成功
      isSending = false
      if (xhr.status >= 200 && xhr.status < 300) {
        console.log(xhr.response)
      }
    }
  }
}

13 JQuery中发送AJAX请求

13.1 发送GET请求

第一个参数为请求的URL,第二个参数为请求参数,第二个参数为请求的回调。

$.get('http://127.0.0.1:3000/msg', {a:1, b:2}, function(data) {
  console.log(data)
})

还可以传入第四个参数,第四个参数则是响应体类型,如:

$.get('http://127.0.0.1:3000/msg', {a:1, b:2}, function(data) {
  console.log(data)
}, 'json')

这里就将响应体的类型设置为了JSON格式。

13.2 发送POST请求

发送POST请求的方法与发送GET请求的方法类似:

$.post('http://127.0.0.1:3000/msg', {a:1, b:2}, function(data) {
  console.log(data)
})

13.3 发送请求通用方法

JQuery中发送请求的通用方法为$对象上的ajax方法,该方法接收的参数为一个对象:

$.ajax({
  // url
  url: 'http://127.0.0.1:3000/msg',
  // 参数
  data: {a:1, b:2},
  // 请求类型
  type: 'GET',
  // 响应体结果的类型
  dataType: 'json',
  // 成功的回调
  success: function(data) {
    console.log(data)
  },
  // 失败的回调 
  error: function() {
    console.log('err')
  },
  // 超时时间
  timeout: 4000,
  // 头信息
  headers: {
    // MyHeaders: 123
  }
})

14 Axios中发送AJAX请求

Axios是目前前端领域中最热门的AJAX工具库,也是Vue和React官方推荐的工具库。

14.1 Axios发送GET请求

axios.defaults.baseURL = 'http://127.0.0.1:3000'
axios.get('/msg', {
  // url参数
  params: {
    a: 1,
    b: 2
  },
  // 设置请求头信息
  headers: {
    MyHeaders: 123
  }
}).then(value => {
  // 基于Promise
  console.log(value)
})

14.2 Axios发送POST请求

发送POST请求可以设置请求体信息,放在post方法的第二个参数:

axios.defaults.baseURL = 'http://127.0.0.1:3000'
axios.post('/msg', {
  username: 'admin',
  password: '123456'
}, {
  // url参数
  params: {
    a: 1,
    b: 2
  },
  // 设置请求头信息
  headers: {
    MyHeaders: 123
  },
}).then(value => {
  // 基于Promise
  console.log(value)
})

14.3 Axios发送请求通用方法

axios.defaults.baseURL = 'http://127.0.0.1:3000'
axios({
  // 请求方法
  method: 'POST',
  // url
  url: '/msg',
  // url参数
  params: {
    a: 1,
    b: 2
  },
  // 头信息
  headers: {
    MyHeaders: 123
  },
  // 请求体参数
  data: {
    username: 'admin',
    password: '123456'
  }
})

15 fetch方法发送AJAX请求

fetch方法全局自带,并且返回一个Promise对象。

fetch('http://127.0.0.1:3000/msg', {
  // 请求方法
  method: 'POST',
  // 请求头
  headers: {
    MyHeaders: 123
  },
  // 请求体
  body: 'username=admin&password=123456'
}).then((response) => {
  // 调用fetch中的text方法,再返回一个Promise对象
  return response.text()
  // 如果服务器返回的是json数据,可以使用json方法
  // return response.json()
}).then((response) => {
  // 获取到最终的响应数据
  console.log(response)
})
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值