JavaScript网络请求Ajax

JavaScript的Ajax(Asynchronous JavaScript and XML)是一种在后台与服务器进行异步通信的技术,能够通过JavaScript在不刷新整个页面的情况下向服务器发送请求并获取响应。

使用Ajax可以实现以下功能:

  1. 动态更新页面内容:通过向服务器发送异步请求,可以在不刷新整个页面的情况下更新特定部分的内容。这可以提高用户体验并减少数据传输量。

  2. 异步加载数据:通过Ajax,可以在页面加载时异步加载数据,而不是等待整个页面加载完成。这样可以加快页面加载速度,并提高用户体验。

  3. 提交表单数据:通过Ajax,可以在不刷新整个页面的情况下将表单数据发送到服务器进行处理。这样可以实现即时验证和提交,并减少页面刷新的次数。

  4. 实时数据更新:通过使用Ajax轮询或长轮询技术,可以实现实时更新数据的功能,如聊天室、即时通讯等。

在JavaScript中,可以使用XMLHttpRequest对象来实现Ajax请求。XMLHttpRequest提供了向服务器发送请求和处理响应的方法和属性。以下是一个简单的示例:

var xhr = new XMLHttpRequest();

xhr.open('GET', 'https://api.example.com/data', true);

xhr.onreadystatechange = function() {
  if (xhr.readyState === 4 && xhr.status === 200) {
    var response = JSON.parse(xhr.responseText);
    console.log(response);
  }
};

xhr.send();

在上面的示例中,我们创建了一个XMLHttpRequest对象,并使用open方法指定了请求的URL和请求方法(GET)。然后,我们使用onreadystatechange事件处理程序来监听请求状态的变化。当readyState为4(请求已完成)且status为200(成功)时,我们通过responseText属性获取服务器的响应内容,并将其解析为JSON格式。

除了使用GET方法,还可以使用POST方法发送数据到服务器。以下是一个使用POST方法发送表单数据的示例:

var xhr = new XMLHttpRequest();
var formData = new FormData();

formData.append('username', 'myUsername');
formData.append('password', 'myPassword');

xhr.open('POST', 'https://api.example.com/login', true);

xhr.onreadystatechange = function() {
  if (xhr.readyState === 4 && xhr.status === 200) {
    var response = JSON.parse(xhr.responseText);
    console.log(response);
  }
};

xhr.send(formData);

在上面的示例中,我们创建了一个FormData对象,并使用append方法添加了要发送的表单数据。然后,我们使用open方法指定了请求的URL和请求方法(POST)。最后,通过send方法发送请求,并将FormData对象作为参数传递给send方法。

使用Ajax可以大大提升网页的交互性和用户体验,并且可以实现实时更新数据、动态加载内容和提交表单等功能。

1-ajax案例

当然,我可以为您举一个简单的AJAX异步请求的例子。以下是一个使用原生JavaScript实现的AJAX GET请求案例,用于从服务器获取JSON数据:

// 创建一个新的XMLHttpRequest对象
var xhr = new XMLHttpRequest();

// 配置请求信息
xhr.open('GET', 'https://api.example.com/data/123', true); // 第三个参数为true表示异步请求

// 设置请求完成后的回调函数
xhr.onload = function() {
  if (xhr.status === 200) { // HTTP状态码200表示成功
    var data = JSON.parse(xhr.responseText); // 解析返回的JSON字符串为JavaScript对象
    console.log(data); // 在控制台打印出响应的数据
    // 这里可以进一步操作获取到的数据,例如更新页面内容
    document.getElementById('result').innerHTML = data.title;
  } else {
    console.error('请求失败:' + xhr.status);
  }
};

// 发送请求
xhr.send();

// 错误处理
xhr.onerror = function() {
  console.error('发生网络错误');
};

在这个例子中,我们创建了一个AJAX请求来访问https://api.example.com/data/123这个API端点,并在请求成功时处理返回的JSON数据。如果HTTP状态码是200(表示请求成功),则将返回的数据解析为JSON并展示在页面上具有ID为’result’的元素中。同时,我们也设置了错误处理函数以应对可能出现的网络错误。

请注意,在现代JavaScript开发中,通常会使用Fetch API或者jQuery、axios等库来简化AJAX请求的编写。以下是使用Fetch API的一个相似例子:

fetch('https://api.example.com/data/123')
  .then(response => response.json()) // 将响应体转换为JSON
  .then(data => {
    console.log(data);
    document.getElementById('result').innerHTML = data.title;
  })
  .catch(error => {
    console.error('请求失败:', error);
  });

2-ajax同步异步

在jQuery的Ajax请求中,同步和异步请求的区别主要在于是否阻塞浏览器的后续代码执行。下面分别给出同步(synchronous)和异步(asynchronous)请求的例子:

同步请求例子

$.ajax({
  url: "/api/sync-data",
  type: "GET",
  async: false, // 设置为false表示进行同步请求
  dataType: "json",
});

// 在同步请求下,直到服务器响应完成,以下代码才会被执行
console.log("这段代码会在Ajax请求完成后执行");

**注意:**现代浏览器通常不推荐使用同步Ajax请求,因为它会导致浏览器锁定,直至请求完成,用户体验极差,而且大部分现代浏览器已默认不允许在主线程上执行同步Ajax请求。

异步请求例子

这是更常见的用法:

$.ajax({
  url: "/api/async-data",
  type: "GET",
  dataType: "json",
  success: function(response) {
    console.log("收到服务器数据:", response);
    // 这段代码在服务器返回响应后异步执行
  },
  error: function(xhr, status, error) {
    console.error("请求失败:", status, error);
  },
});

console.log("这段代码会立即执行,不会等待Ajax请求完成");

在异步请求中,successdonethen 回调函数将在服务器响应就绪后异步执行,而不会阻塞后续的JavaScript代码。这意味着Ajax请求发出后,紧跟其后的代码会立即执行,不受服务器响应时间的影响。

3-请求方式-1

在HTTP协议中,常见的请求方式主要有GET、POST、PUT、DELETE等。这里分别给出一个使用jQuery的GET请求的例子:

GET请求例子

$.ajax({
  url: "/api/data",
  type: "GET", // 使用GET方法请求数据
  dataType: "json",
  success: function(response) {
    console.log("获取的数据:", response);
  },
  error: function(xhr, status, error) {
    console.error("GET请求失败:", status, error);
  },
});

4-请求方式-2

如果您是指其他的HTTP请求方式,例如POST,请看下面的例子:


// 使用原生XMLHttpRequest实现POST请求
var xhr = new XMLHttpRequest();
xhr.open('POST', 'https://api.example.com/data', true);
xhr.setRequestHeader("Content-Type", "application/json;charset=UTF-8"); // 设置请求头

xhr.onload = function() {
  if (xhr.status === 200) {
    var data = JSON.parse(xhr.responseText);
    console.log(data);
  } else {
    console.error('请求失败:' + xhr.status);
  }
};

xhr.onerror = function() {
  console.error('发生网络错误');
};

var data = { key1: 'value1', key2: 'value2' }; // 要发送的数据
xhr.send(JSON.stringify(data));

在这个POST请求示例中,我们不仅设置了请求方式为POST,还设置了请求头Content-Type表明发送的数据格式为JSON,并使用send方法发送了一个JSON对象。

5-ajax封装-1

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <script src="./util.js"></script>
    <script>
        // ajax({
        //     url:"http://localhost:3000/users",
        //     data:{
        //         username:"kerwin222",
        //         password:"789"
        //     },
        //     success:function(res){
        //         console.log("sucess",res)
        //     },
        //     error:function(err){
        //         console.log("error",err)
        //     }
        // })

        ajax({
            url:"http://localhost:3000/users",
            method:"POST",
            data:{
                username:"kerwin3333",
                password:"789"
            },
            headers:{
                "content-type":"application/json"
            },
            success:function(res){
                console.log("sucess",res)
            },
            error:function(err){
                console.log("error",err)
            }
        })
    </script>
</body>
</html>
{
  "users": [
    {
      "username": "ximen",
      "password": "789",
      "id": 5
    },
    {
      "username": "kuo",
      "password": "789",
      "id": 6
    },
    {
      "username": "kuo",
      "password": "789",
      "id": 7
    },
    {
      "username": "kuo",
      "password": "789",
      "id": 8
    },
    {
      "username": "kuo",
      "password": "789",
      "id": 9
    },
    {
      "username": "kuo",
      "password": "789",
      "id": 10
    },
    {
      "username": "kuo",
      "password": "789",
      "id": 11
    },
    {
      "username": "kuo",
      "password": "789",
      "id": 12
    },
    {
      "username": "kuo",
      "password": "789",
      "id": 13
    },
    {
      "username": "kuo",
      "password": "789",
      "id": 14
    },
    {
      "username": "kuo",
      "password": "789",
      "id": 15
    },
    {
      "username": "kuo",
      "password": "789",
      "id": 16
    },
    {
      "username": "kuo",
      "password": "789",
      "id": 17
    },
    {
      "username": "kuo",
      "password": "789",
      "id": 18
    },
    {
      "username": "kuo",
      "password": "789",
      "id": 19
    },
    {
      "username": "kuo",
      "password": "789",
      "id": 20
    },
    {
      "username": "kuo",
      "password": "789",
      "id": 21
    },
    {
      "username": "kuo",
      "password": "789",
      "id": 22
    },
    {
      "username": "kuo",
      "password": "789",
      "id": 23
    },
    {
      "username": "kuo",
      "password": "789",
      "id": 24
    },
    {
      "username": "kuo",
      "password": "789",
      "id": 25
    },
    {
      "username": "kuo",
      "password": "789",
      "id": 26
    },
    {
      "username": "kuo1",
      "password": "789",
      "id": 27
    },
    {
      "username": "kuo1",
      "password": "789",
      "id": 28
    },
    {
      "username": "kuo1",
      "password": "789",
      "id": 29
    },
    {
      "username": "kuo1",
      "password": "789",
      "id": 30
    },
    {
      "username": "kuo1",
      "password": "789",
      "id": 31
    },
    {
      "username": "kuo1",
      "password": "789",
      "id": 32
    },
    {
      "username": "kuo1",
      "password": "789",
      "id": 33
    },
    {
      "username": "kuo1",
      "password": "789",
      "id": 34
    }
  ],
  "list": [
    "1111",
    "2222",
    "3333"
  ]
}
function queryStringify(obj) {
  let str = ''
  for (let k in obj) str += `${k}=${obj[k]}&`

  //username=kerwin&password=789&
  return str.slice(0, -1)
}

// 封装 ajax
function ajax(options) {
  let defaultoptions = {
    url: "",
    method: "GET",
    async: true,
    data: {},
    headers: {},
    success: function () { },
    error: function () { }
  }
  let { url, method, async, data, headers, success, error } = {
    ...defaultoptions,
    ...options
  }

  // console.log(url, method, async, data, headers, success, error)

  if (typeof data === 'object' && headers["content-type"]?.indexOf("json") > -1) {
    data = JSON.stringify(data)
  }
  else {
    data = queryStringify(data)
  }
  // // 如果是 get 请求, 并且有参数, 那么直接组装一下 url 信息
  if (/^get$/i.test(method) && data) url += '?' + data
  
  // // 4. 发送请求
  const xhr = new XMLHttpRequest()
  xhr.open(method, url, async)
  xhr.onload = function () {
    if (!/^2\d{2}$/.test(xhr.status)) {
      // console.log(error)
      error(`错误状态码:${xhr.status}`) //回调
      return
    }

    // 执行解析


    try {
      let result = JSON.parse(xhr.responseText)
      success(result)
    } catch (err) {
      error('解析失败 ! 因为后端返回的结果不是 json 格式字符串')
    }
  }

  // console.log(22222)

  // // 设置请求头内的信息
  for (let k in headers) xhr.setRequestHeader(k, headers[k])
  if (/^get$/i.test(method)) {
    xhr.send()
  } else {
    xhr.send(data)
  }

  // xhr.send(data)
}

6-ajax封装-2

以下是一个使用原生JavaScript封装的简单Ajax函数示例,它支持GET和POST请求:

// 简单的AJAX封装函数
function ajaxRequest(method, url, data = null, callbackSuccess, callbackError) {
  var xhr = new XMLHttpRequest(); // 创建XMLHttpRequest对象

  xhr.onreadystatechange = function() { // 设置状态改变时的回调函数
    if (xhr.readyState === 4) { // 成功完成请求(请求已发送、接收数据完毕)
      if (xhr.status >= 200 && xhr.status < 300 || xhr.status === 304) { // HTTP状态码正常
        try {
          var response = JSON.parse(xhr.responseText); // 如果返回的是JSON,则解析为JS对象
          callbackSuccess(response);
        } catch (e) {
          callbackSuccess(xhr.responseText); // 非JSON格式直接返回原始响应文本
        }
      } else {
        callbackError(xhr.status, xhr.statusText); // 请求失败时调用错误回调
      }
    }
  };

  // 根据HTTP方法设置请求
  if (method === 'POST') {
    xhr.open('POST', url, true);
    xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded"); // POST请求一般设置内容类型
    xhr.send(encodeFormData(data)); // 对POST数据进行URL编码后发送
  } else if (method === 'GET') {
    xhr.open('GET', url + '?' + encodeFormData(data), true); // GET请求将数据附加在URL后面
    xhr.send();
  }

  // 辅助函数:对数据进行URL编码
  function encodeFormData(data) {
    return Object.keys(data).map(key => `${encodeURIComponent(key)}=${encodeURIComponent(data[key])}`).join('&');
  }
}

// 使用封装好的ajax函数的例子:
var requestData = { id: 123, name: 'John Doe' };
ajaxRequest('GET', '/api/data', requestData, function(response) {
  console.log('成功获取数据:', response);
}, function(status, statusText) {
  console.error(`请求失败,状态码:${status},错误信息:${statusText}`);
});

// POST请求例子
ajaxRequest('POST', '/api/submit', requestData, function(response) {
  console.log('数据提交成功,服务器响应:', response);
}, function(status, statusText) {
  console.error(`数据提交失败,状态码:${status},错误信息:${statusText}`);
});

这个函数接受5个参数:

  • method:HTTP请求方法,如’GET’或’POST’
  • url:请求的URL
  • data:要发送的数据(对于GET是查询字符串形式,对于POST则是键值对)
  • callbackSuccess:请求成功后的回调函数,处理服务器返回的数据
  • callbackError:请求失败后的回调函数,处理错误信息

注意:实际开发中,为了兼容现代浏览器以及更好地处理各种情况,可能需要更复杂的封装,例如支持其他HTTP方法、设置超时、预处理请求头等。

7-ajax前后端交互案例

当然,这里是一个使用jQuery库进行Ajax前后端交互的POST请求示例:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
</head>
<body>

<!-- 假设有一个表单 -->
<form id="myForm">
    <input type="text" name="username" placeholder="用户名">
    <input type="password" name="password" placeholder="密码">
    <button type="submit">登录</button>
</form>

<div id="response"></div>

<script>
$(document).ready(function() {
    // 为表单绑定提交事件
    $("#myForm").submit(function(event) {
        event.preventDefault(); // 阻止表单默认提交行为
        
        var formData = $(this).serialize(); // 序列化表单数据

        $.ajax({
            type: "POST", // 请求类型为POST
            url: "/api/login", // 后端处理登录请求的URL
            data: formData, // 发送给后端的数据
            dataType: "json", // 指定服务器响应的数据类型(这里假设是JSON)
            success: function(response) { // 请求成功时的回调函数
                if (response.status === 'success') {
                    $("#response").html("登录成功!"); // 在页面上显示成功的提示信息
                    // 这里可以进一步执行登录成功的操作,如跳转到主页等
                } else {
                    $("#response").html("登录失败:" + response.message); // 显示错误信息
                }
            },
            error: function(xhr, status, error) { // 请求失败时的回调函数
                $("#response").html("请求出错:" + error);
            }
        });
    });
});
</script>

</body>
</html>

在这个案例中,当用户点击登录按钮提交表单时,AJAX会发送一个POST请求到 /api/login 这个后端接口,并携带表单中的用户名和密码数据。后端接收到请求并验证用户身份后,会返回一个JSON格式的响应。前端根据响应的状态来更新页面内容,显示登录结果或错误信息。

8-回调地狱问题

回调地狱问题在JavaScript中常见于异步编程,特别是在Node.js环境和早期的前端Ajax请求处理中。以下是一个使用纯回调函数实现的文件读取操作的例子,展示了回调地狱的情况:

const fs = require('fs'); // 假设这是Node.js环境下的文件系统模块

// 回调地狱例子:
fs.readFile('file1.txt', 'utf8', function(err, data1) {
  if (err) {
    console.error('Error reading file1:', err);
    return;
  }
  
  console.log('File1 contents:', data1);

  fs.readFile('file2.txt', 'utf8', function(err, data2) {
    if (err) {
      console.error('Error reading file2:', err);
      return;
    }
    
    console.log('File2 contents:', data2);

    fs.readFile('file3.txt', 'utf8', function(err, data3) {
      if (err) {
        console.error('Error reading file3:', err);
        return;
      }

      console.log('File3 contents:', data3);

      // 进行下一步需要基于data1、data2和data3的操作...
    });
  });
});

在这个例子中,我们有三个连续的fs.readFile调用,每个调用都依赖于前一个调用的结果。这种嵌套的回调函数结构导致代码变得非常难以阅读和维护,尤其是在需要处理更多层级异步操作时,这就是所谓的“回调地狱”。

为了解决这个问题,可以采用Promise、async/await等现代JavaScript特性来重构这段代码,使其扁平化并提高可读性与可维护性。

最后求点赞,求分享,求抱抱…

  • 28
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值