Ajax和Axios的初步学习

Ajax

一、什么是 Ajax?

Ajax (Asynchronous JavaScript and XML) 是一种无需重新加载整个网页的情况下,能够更新部分网页的技术。通过在后台与服务器进行少量数据交换,Ajax 可以使网页实现异步更新。

主要特性:

  • 异步性 (Asynchronous): 可以在不阻塞用户界面的情况下与服务器进行通信。

  • 局部更新 (Partial Updates): 只更新网页的一部分,而不是整个页面,提高了用户体验。

  • 基于标准: Ajax 不是一种新技术,而是几种现有技术的组合,包括JavaScript, XML, HTML, CSS。

二、Ajax 的核心对象:XMLHttpRequest

XMLHttpRequest (XHR) 对象是 Ajax 的核心。它允许浏览器在后台与服务器进行通信。

三、基本语法和步骤 (XMLHttpRequest)

1.创建 XMLHttpRequest 对象:

javascript 复制代码
let xhr;

if (window.XMLHttpRequest) {  // 现代浏览器
  xhr = new XMLHttpRequest();
} else {  // IE6, IE5
  xhr = new ActiveXObject("Microsoft.XMLHTTP");
}

2.配置请求 (open 方法):

javascript 复制代码
xhr.open(method, url, async, username, password);
  • method: HTTP 请求方法 (GET, POST, PUT, DELETE 等)。通常使用 GET 或 POST。

  • url: 服务器端脚本的 URL。

  • async: (可选) 布尔值,指示请求是否异步执行。 默认为 true(异步)。

  • username: (可选) 用于身份验证的用户名。

  • password: (可选) 用于身份验证的密码。

javascript 复制代码
xhr.open('GET', 'data.txt', true); // 异步 GET 请求
xhr.open('POST', 'submit.php', true); // 异步 POST 请求

3.设置请求头 (可选):

javascript 复制代码
xhr.setRequestHeader(header, value);
  • header: 请求头的名称。

  • value: 请求头的值。

重要: 对于 POST 请求,通常需要设置 Content-Type 请求头。

示例:

javascript 复制代码
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded'); // 常用于 POST
xhr.setRequestHeader('Content-Type', 'application/json'); //  POST 发送 JSON 数据

4.发送请求 (send 方法):

javascript 复制代码
xhr.send(body); // body 是要发送的数据

body: (可选) 要发送到服务器的数据。

  • 对于 GET 请求,通常 bodynull。 数据应该附加到 URL 上(例如:url**?**param1=value1&param2=value2)。

  • 对于 POST 请求,body 可以是:

    • null (如果没有数据要发送)

    • URL 编码的字符串 (例如:param1=value1&param2=value2)

    • JSON 字符串 (需要设置 Content-Typeapplication/json)

    • **FormData**对象

javascript 复制代码
xhr.send();  // GET 请求,没有数据
xhr.send('name=John&age=30'); // POST 请求,URL 编码的数据
xhr.send(JSON.stringify({name: "John", age: 30}));  // POST 请求,JSON 数据

5.处理服务器响应:

使用 onreadystatechange 事件监听 xhr.readyState 的变化。

javascript 复制代码
xhr.onreadystatechange = function() {
  if (xhr.readyState === 4) {  // 请求完成
    if (xhr.status === 200) { // 请求成功
      // 处理响应数据
      let responseText = xhr.responseText; // 字符串形式的响应数据
      let responseXML = xhr.responseXML;  // 如果服务器返回 XML,可以作为 XML 文档访问

      // 根据你的需求更新页面等
      console.log("Response: " + responseText);
    } else {
      // 处理错误
      console.error("请求失败,状态码:" + xhr.status);
    }
  }
};
  • xhr.readyState: 表示请求的状态。

    • 0: 请求未初始化

    • 1: 服务器连接已建立

    • 2: 请求已接收

    • 3: 请求处理中

    • 4: 请求已完成,且响应已就绪

  • xhr.status: HTTP 状态码。

    • 200: "OK" (成功)

    • 404: "Not Found" (未找到)

    • 500: "Internal Server Error" (服务器内部错误) 等等。

四、示例

1.完整的 GET 请求例子

html 复制代码
<!DOCTYPE html>
<html>
<head>
<title>简单的 Ajax GET 请求</title>
</head>
<body>

<button onclick="loadData()">加载数据</button>
<div id="result"></div>

<script>
function loadData() {
  let xhr;
  if (window.XMLHttpRequest) {
    xhr = new XMLHttpRequest();
  } else {
    xhr = new ActiveXObject("Microsoft.XMLHTTP");
  }

  xhr.onreadystatechange = function() {
    if (xhr.readyState === 4) {
      if (xhr.status === 200) {
        document.getElementById("result").innerHTML = xhr.responseText;
      } else {
        document.getElementById("result").innerHTML = "Error: " + xhr.status;
      }
    }
  };

  xhr.open("GET", "data.txt", true);
  xhr.send();
}
</script>

</body>
</html>

创建一个名为**data.txt** 的文件,内容例如:Hello, Ajax! This is data loaded from the server.

2.完整的 POST 请求例子

html 复制代码
<!DOCTYPE html>
<html>
<head>
<title>简单的 Ajax GET 请求</title>
</head>
<body>

<button onclick="loadData()">加载数据</button>
<div id="result"></div>

<script>
function loadData() {
  let xhr;
  if (window.XMLHttpRequest) {
    xhr = new XMLHttpRequest();
  } else {
    xhr = new ActiveXObject("Microsoft.XMLHTTP");
  }

  xhr.onreadystatechange = function() {
    if (xhr.readyState === 4) {
      if (xhr.status === 200) {
        document.getElementById("result").innerHTML = xhr.responseText;
      } else {
        document.getElementById("result").innerHTML = "Error: " + xhr.status;
      }
    }
  };

  xhr.open("GET", "data.txt", true);
  xhr.send();
}
</script>

</body>
</html>

创建一个名为**submit.php**的PHP文件(或者其他服务器端语言的文件),例如:

php 复制代码
<?php
  $name = $_POST["name"];
  echo "你好, " . htmlspecialchars($name) . "!"; // 使用 htmlspecialchars 防止 XSS 攻击
?>

五、使用 FormData 上传文件

FormData 对象提供了一种表示表单数据的键/值对的简单方式,也可以用于上传文件。

html 复制代码
<!DOCTYPE html>
<html>
<head>
<title>Ajax 上传文件</title>
</head>
<body>

<input type="file" id="fileInput"><br><br>
<button onclick="uploadFile()">上传文件</button>
<div id="result"></div>

<script>
function uploadFile() {
  let xhr;
  if (window.XMLHttpRequest) {
    xhr = new XMLHttpRequest();
  } else {
    xhr = new ActiveXObject("Microsoft.XMLHTTP");
  }

  xhr.onreadystatechange = function() {
    if (xhr.readyState === 4) {
      if (xhr.status === 200) {
        document.getElementById("result").innerHTML = xhr.responseText;
      } else {
        document.getElementById("result").innerHTML = "Error: " + xhr.status;
      }
    }
  };

  const fileInput = document.getElementById("fileInput");
  const file = fileInput.files[0];

  const formData = new FormData();
  formData.append("file", file); // 添加文件到 FormData

  xhr.open("POST", "upload.php", true);
  xhr.send(formData); // 不需要手动设置 Content-Type,浏览器会自动设置
}
</script>

</body>
</html>

创建一个名为**upload.php**的PHP文件(或者其他服务器端语言的文件),例如:

php 复制代码
<?php
if (isset($_FILES["file"])) {
  $file = $_FILES["file"];

  // 安全起见,你应该进行各种检查,例如文件类型、大小等
  // 示例:
  $allowed_types = array("image/jpeg", "image/png", "application/pdf");
  if (!in_array($file["type"], $allowed_types)) {
    echo "Error: Invalid file type.";
    exit;
  }

  $upload_dir = "uploads/"; // 确保该目录存在,并且有写入权限
  $filename = basename($file["name"]); // 获取文件名
  $target_path = $upload_dir . $filename;

  if (move_uploaded_file($file["tmp_name"], $target_path)) {
    echo "文件上传成功!文件名: " . htmlspecialchars($filename);
  } else {
    echo "文件上传失败。";
  }

} else {
  echo "没有文件上传。";
}
?>

Axios

一、什么是 Axios?

Axios 是一个基于 Promise 的 HTTP 客户端,用于浏览器和 Node.js。它允许开发者轻松地发送 HTTP 请求(GET、POST、PUT、DELETE 等),并处理服务器返回的响应。

为什么选择 Axios?

  • 基于 Promise: 可以使用 async/await,使异步代码更易于编写和理解。

  • 浏览器和 Node.js 通用: 同样的代码可以在前后端运行。

  • 自动转换 JSON 数据: 自动将请求数据序列化为 JSON,并自动将响应数据反序列化为 JSON。

  • 拦截器: 可以在请求发送前或响应接收后对数据进行处理(例如,添加认证 Token,处理通用错误)。

  • 取消请求: 可以取消正在进行的请求。

  • 客户端支持防止 CSRF: (通过 XSRF-TOKEN)。

  • 文件上传进度: 支持上传和下载进度的监听。

二、如何安装和引入 Axios?

1. 在浏览器环境 (CDN):

直接在 HTML 文件中引入,引入后,axios 对象会全局可用。

html 复制代码
<script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>

2. 在 Node.js 或前端项目 (npm/yarn):

html 复制代码
npm install axios
# 或者
yarn add axios
javascript 复制代码
import axios from 'axios'; // ES6 模块
// 或者
const axios = require('axios'); // CommonJS 模块

三、Axios 的基本用法和语法

Axios 提供多种方式来发起 HTTP 请求:

1. axios(config) 方法 (通用请求)

这是最通用的方式,通过传入一个配置对象来定义请求。

javascript 复制代码
axios({
  method: 'post', // 请求方法
  url: '/user/12345', // 请求 URL
  data: { // POST 请求体数据 (会被自动序列化为 JSON)
    firstName: 'Fred',
    lastName: 'Flintstone'
  },
  headers: { // 请求头
    'Content-Type': 'application/json',
    'Authorization': 'Bearer YOUR_TOKEN'
  },
  timeout: 1000, // 请求超时时间,单位毫秒
  params: { // GET 请求参数 (会附加到 URL 后)
    ID: 12345
  }
})
.then(function (response) {
  console.log(response.data); // 服务器响应数据
  console.log(response.status); // HTTP 状态码
  console.log(response.headers); // 响应头
})
.catch(function (error) {
  console.error(error); // 请求失败或服务器返回非 2xx 状态码
});

2. 请求方法别名 (GET, POST, PUT, DELETE 等)

Axios 为常见的 HTTP 方法提供了便捷的别名方法。这些方法接受 URL 作为第一个参数,数据作为第二个参数(POST/PUT等),配置作为第三个参数。

GET 请求:axios.get(url, [config])

javascript 复制代码
// 获取用户数据
axios.get('/user?ID=12345')
  .then(response => console.log(response.data))
  .catch(error => console.error(error));

// 或者通过 params 配置
axios.get('/user', {
  params: {
    ID: 12345
  },
  headers: {'X-Custom-Header': 'foobar'}
})
.then(response => console.log(response.data))
.catch(error => console.error(error));

DELETE 请求:axios.delete(url, [config])

javascript 复制代码
// 删除用户数据
axios.delete('/user/12345')
  .then(response => console.log(response.data))
  .catch(error => console.error(error));

POST 请求:axios.post(url, data, [config])

javascript 复制代码
// 创建新用户
axios.post('/user', {
  firstName: 'Fred',
  lastName: 'Flintstone'
})
.then(response => console.log(response.data))
.catch(error => console.error(error));

// 例如上传 FormData
const formData = new FormData();
formData.append('file', fileInput.files[0]);
formData.append('name', 'My Document');

axios.post('/upload', formData, {
  headers: {
    'Content-Type': 'multipart/form-data' // 对于 FormData,通常浏览器会自动设置,但显式写明也没错
  }
})
.then(response => console.log(response.data))
.catch(error => console.error(error));

PUT 请求:axios.put(url, data, [config])

javascript 复制代码
// 更新用户数据
axios.put('/user/12345', {
  age: 30
})
.then(response => console.log(response.data))
.catch(error => console.error(error));

其他方法:**axios.head(url, [config]), axios.options(url, [config])axios.patch(url, data, [config])**用法与上述类似。

四、Axios 响应结构

无论请求成功与否,Axios 返回的 Promise 都会解析为一个响应对象。

成功响应 (在 .then() 中收到):

javascript 复制代码
{
  data: {}, // 服务器提供的响应数据
  status: 200, // HTTP 状态码
  statusText: 'OK', // HTTP 状态信息
  headers: {}, // 响应头
  config: {}, // 请求配置对象
  request: {} // 发出请求的 XMLHttpRequest 对象或 http.ClientRequest 实例
}

错误响应 (在 .catch() 中收到):

javascript 复制代码
// error 对象通常包含以下属性:
{
  message: 'Error message', // 错误消息,例如 "Network Error"
  name: 'AxiosError', // 错误名称
  code: 'ERR_BAD_REQUEST', // 错误码,例如 ECONNABORTED (请求超时)
  config: {}, // 请求配置对象
  request: {}, // 发出请求的 XMLHttpRequest 或 http.ClientRequest 实例
  response: { // 如果服务器有响应 (即使是 4xx/5xx 状态码)
    data: {},
    status: 404,
    statusText: 'Not Found',
    headers: {},
    config: {},
    request: {}
  }
}

区分请求成功和服务器错误:

Axios 默认只将 HTTP 状态码为 2xx 的响应视为成功。其他状态码 (如 4xx, 5xx) 都会被视为错误,进入 .catch() 块。你可以在配置中修改这一行为:

javascript 复制代码
axios.get('/some-data', {
  validateStatus: function (status) {
    return status >= 200 && status < 300 || status === 404; // 允许 2xx 或 404 状态码进入 .then()
  }
})
.then(response => { /* ... */ })
.catch(error => { /* ... */ });

五、Axios 实例 (创建自定义配置的实例)

当你的应用有多个不同配置的 API 地址或请求需求时,创建 Axios 实例非常有用。

javascript 复制代码
const instance = axios.create({
  baseURL: 'https://some-domain.com/api/', // 基础 URL
  timeout: 5000,
  headers: {'X-Custom-Header': 'foobar'}
});

// 使用实例发送请求
instance.get('/user/12345')
  .then(response => console.log(response.data));

instance.post('/another-endpoint', {
  message: 'Hello'
})
.then(response => console.log(response.data));

所有通过 instance 发送的请求都会继承 instance 的配置。

相关推荐
贵沫末10 分钟前
React——基础
前端·react.js·前端框架
aklry21 分钟前
uniapp三步完成一维码的生成
前端·vue.js
Rubin9329 分钟前
判断元素在可视区域?用于滚动加载,数据埋点等
前端
爱学习的茄子29 分钟前
AI驱动的单词学习应用:从图片识别到语音合成的完整实现
前端·深度学习·react.js
用户38022585982429 分钟前
使用three.js实现3D地球
前端·three.js
程序无bug32 分钟前
Spring 面向切面编程AOP 详细讲解
java·前端
zhanshuo32 分钟前
鸿蒙UI开发全解:JS与Java双引擎实战指南
前端·javascript·harmonyos
软件黑马王子37 分钟前
C#系统学习第八章——字符串
开发语言·学习·c#
撰卢1 小时前
如何提高网站加载速度速度
前端·javascript·css·html
10年前端老司机1 小时前
在React项目中如何封装一个可扩展,复用性强的组件
前端·javascript·react.js