Ajax基础

传统网站中存在的问题

  • 网速慢的情况下,页面加载时间长,用户只能等待
  • 表单提交后,如果一项内容不合格,需要重新填写所有表单内容
  • 页面跳转,重新加载页面,造成资源浪费,增加用户等待时间

什么是Ajax

Asynchronous JavaScript and XML(异步的 JavaScript 和 XML)使用内置的XMLHttpRequest 和 fetch 对象,实现和服务端进行数据交互,可以实现页面无刷新更新数据,提高用户体验

Ajax的应用场景

  • 页面上拉加载更多数据
  • 列表数据无刷新分页
  • 表单项离开焦点数据验证
  • 搜索框提示文字下拉列表

Ajax的运行环境

Ajax 技术需要运行在网站环境中才能生效

Ajax运行原理及实现

Ajax运行原理

Ajax 相当于浏览器发送请求与接收响应的代理人,以实现在不影响用户浏览页面的情况下,局部更新页面数据,从而提高用户体验
image.png

Ajax发送get请求

  1. // 1. 创建对象
  2. const xhr = new XMLHttpRequest()
  3. // 2. 配置参数
  4. xhr.open('get', url, true) // boolean值表示是否异步
  5. // 3. 绑定事件
  6. xhr.onload = function() {
  7. let responseText = JSON.parse(xhr.responseText)
  8. console.log(responseText)
  9. }
  10. // 4. 发送请求
  11. xhr.send()

服务器端响应数据的格式

在真实的项目中,服务器端大多数情况下会以JSON对象作为响应数据的格式。当客户端拿到响应数据时,要将 JSON 数据和 HTML 字符串进行拼接,然后将拼接的结果展示在页面中。在 http 请求与响应的过程中,无论是请求参数还是响应内容,如果是对象类型,最终都会被转换为对象字符串进行传输。

JSON.parse(xhr.responseText)

请求参数传递

  • get请求方式

image.png

  • post请求方式

image.png

请求参数的格式

  • application/x-www-form-urlencoded
    • 参数变成 key1=value1&key2=value2 的形式
  • multipart/form-data
    • 一般上传文件时使用
      1. let formData = new FormData()
      2. formData.append('username', 'abcdefg')
      3. formData.append('password', '123456')
      4. let url = 'http://rap2api.taobao.org/app/mock/244238/register'
      5. let xhr = new XMLHttpRequest()
      6. xhr.open('POST', url, true)
      7. xhr.onload = function(){
      8. if(xhr.status === 200 || xhr.status === 304) {
      9. console.log(JSON.parse(xhr.responseText))
      10. } else {
      11. console.log('接口异常')
      12. }
      13. }
      14. xhr.send(formData )
      ```javascript // 案例




const $ = s => document.querySelector(s) const $submit = $(‘[type=submit]’) const $form = $(‘form’) const $msg = $(‘#msg’)

let url = ‘http://rap2api.taobao.org/app/mock/244238/register

$form.onsubmit = function(e) { e.preventDefault() //这里校验

let formData = new FormData($form) let xhr = new XMLHttpRequest() xhr.open(‘POST’, url, true) xhr.onload = function(){ if(xhr.status === 200 || xhr.status === 304) { let data = JSON.parse(xhr.responseText) $msg.innerText = data.msg || data.errMsg } else { $msg.innerText = ‘接口异常’ } } xhr.send(formData )
}

  1. <a name="Eqwri"></a>
  2. ### 获取服务器端的响应
  3. **Ajax状态码**<br />在创建ajax对象,配置ajax对象,发送请求,以及接收完服务器端响应数据,这个过程中的每一个步骤都会对应一个数值,这个数值就是ajax状态码<br />0:请求未初始化(还没有调用open()<br />1:请求已经建立,但是还没有发送(还没有调用send())<br />2:请求已经发送<br />3:请求正在处理中,通常响应中已经有部分数据可以用了<br />4:响应已经完成,可以获取并使用服务器的响应了<br />![image.png](https://cdn.nlark.com/yuque/0/2020/png/2205407/1605084668138-bc9616a6-168c-45a8-9770-7f97e37e5310.png#height=90&id=vtz6I&margin=%5Bobject%20Object%5D&name=image.png&originHeight=111&originWidth=423&originalType=binary&ratio=1&size=3872&status=done&style=none&width=344)<br />![image.png](https://cdn.nlark.com/yuque/0/2020/png/2205407/1605085138534-732e8fbb-7df1-4279-bc4a-1723437b3daf.png#height=315&id=EvCzD&margin=%5Bobject%20Object%5D&name=image.png&originHeight=462&originWidth=1051&originalType=binary&ratio=1&size=41823&status=done&style=none&width=717)<br />**两种获取服务器端响应方式区别**<br />![image.png](https://cdn.nlark.com/yuque/0/2020/png/2205407/1605084997050-ce8054db-be03-4641-8af7-39dda28bf94c.png#height=212&id=ld9ZG&margin=%5Bobject%20Object%5D&name=image.png&originHeight=212&originWidth=918&originalType=binary&ratio=1&size=19821&status=done&style=none&width=918)
  4. <a name="gxMIQ"></a>
  5. ### Ajax错误处理
  6. ![image.png](https://cdn.nlark.com/yuque/0/2020/png/2205407/1605085407568-3f9f5873-d5f1-45a4-8095-d7b2a4058dff.png#height=378&id=Bj68H&margin=%5Bobject%20Object%5D&name=image.png&originHeight=378&originWidth=787&originalType=binary&ratio=1&size=39010&status=done&style=none&width=787)
  7. <a name="a5VMF"></a>
  8. ### 案例
  9. ```javascript
  10. // 发送get请求
  11. let url = 'http://rap2api.taobao.org/app/mock/244238/weather?city=北京'
  12. let xhr = new XMLHttpRequest()
  13. // 方法一
  14. xhr.open('get', url, true)
  15. xhr.onreadystatechange = function() {
  16. if(xhr.readyState === 4) {
  17. if(xhr.status >= 200 && xhr.status < 300 || xhr.status === 304) {
  18. console.log(JSON.parse(xhr.responseText))
  19. } else {
  20. console.log('数据异常')
  21. }
  22. }
  23. }
  24. xhr.onerror = function() {
  25. console.log('服务器异常')
  26. }
  27. xhr.send()
  28. // 方法二
  29. xhr.open('GET', url, true)
  30. xhr.onload = function(){
  31. if((xhr.status >= 200 && xhr.status < 300) || xhr.status === 304){
  32. console.log(JSON.parse(xhr.responseText)) // 将JSON字符串解析成对象
  33. } else {
  34. console.log('数据异常')
  35. }
  36. }
  37. xhr.onerror = function(){ // 可选
  38. console.log('服务器异常')
  39. }
  40. xhr.send()
// 发送post请求

let url = 'http://rap2api.taobao.org/app/mock/244238/login' 
let xhr = new XMLHttpRequest()

xhr.timeout = 3000       //可选,设置请求超时时间
xhr.open('post', url, true)
xhr.setRequestHeader('Content-type', 'application/x-www-form-urlencoded')
xhr.onload = function(){
    if((xhr.status >= 200 && xhr.status < 300) || xhr.status === 304){
        console.log(JSON.parse(xhr.responseText))
    } else {
        console.log('响应异常')
    }
}
xhr.ontimeout = function() { 
  console.log('请求超时') 
}
xhr.onerror = function(){ 
  console.log('服务器异常') 
}
xhr.send('username=liudehua&password=12345678')

Ajax封装

const request = (url, params, onsuccess, onerror) => {
  url = url + '?' + Object.entries(params).map(arr => arr[0] + '=' + arr[1]).join('&')
    let xhr = new XMLHttpRequest()
    xhr.open('GET', url, true) 
    xhr.onload = function(){
    if(xhr.status === 200 || xhr.status === 304) {
      onsuccess(JSON.parse(xhr.responseText))
    } else {
      onerror()
    }
    }
    xhr.onerror = onerror
    xhr.send()
}
request('http://rap2api.taobao.org/app/mock/244238/weathe', {city: '杭州'}, 
        data => {
                    console.log('请求成功')
                    console.log(data)
                }, 
        () => {
                    console.log('接口异常')
                }
)