当前位置: 首页 > article >正文

JavaScript 发起网络请求 axios、fetch、async / await

目录

fetch

发送 GET 请求(fetch)

发送 POST 请求(fetch)

处理后台异常响应

async / await

async

await

发送 GET 请求(async / await fetch)

发送 POST 请求(async / await fetch)

Axios

发送 GET 请求(axios)

发送 POST 请求(axios)

发送 GET 请求(async / await axios)

发送 POST 请求(async / await axios)

请求拦截器

响应拦截器

取消请求

中止请求


fetch

fetch 是现代浏览器中用于发起网络请求的 API,它提供了一种更加简洁和强大的方式来获取资源(例如从网络加载数据)。与传统的 XMLHttpRequest 相比,fetch 提供了更简洁的语法和更强的功能,并且返回的是 Promise,使得异步编程更加易于理解和处理。

fetch 允许我们通过 HTTP 请求(如 GET、POST、PUT、DELETE 等方法)向服务器请求数据,并异步地处理请求结果。它是异步的,意味着不会阻塞其他 JavaScript 代码的执行。

语法:

fetch(url, options)

    .then(response => response.json())                  // 将响应体解析为 JSON

    .then(data => console.log(data))                       // 处理返回的数据

    .catch(error => console.error('Error:', error));    // 错误处理

参数说明:

  • url: 请求的目标 URL(可以是相对路径或绝对路径)。
  • options: 可选的配置对象,包含请求方法、头信息、请求体等。

options 常用选项:

method:请求方式,默认为 GET。常见值有 POST、PUT、DELETE、PATCH 等。

示例:

fetch('https://example.com', {
    method: 'POST',
});

headers:请求头,通常是一个对象,包含键值对。

示例:

fetch('https://example.com', {
    headers: {
        'Content-Type': 'application/json',
        'Authorization': 'Bearer token',
    }
});

body:请求体,仅在方法是 POST、PUT 等时使用,通常是 JSON 格式的数据。

示例:

fetch('https://example.com', {
    method: 'POST',
    headers: {
        'Content-Type': 'application/json'
    },
    body: JSON.stringify({ name: 'John', age: 30 })
});

mode:控制请求的跨域行为,常用的值有 no-cors、cors 和 same-origin。默认为 cors。

  • no-cors:不携带跨域凭证,限制请求返回内容的访问。
  • cors:允许跨域请求,需目标服务器支持 CORS。
  • same-origin:仅允许同源请求(即相同的协议、域名和端口)。

示例:

fetch('https://example.com', {
  mode: 'no-cors', // 不发送跨域请求
});

cache:控制缓存行为,常用值有 default、no-store、reload 等。

  • default:按常规缓存机制处理,有缓存就用缓存,没有缓存就从网络加载。
  • no-store:不缓存,始终从网络加载。
  • reload:强制重新加载,不使用缓存(一点缓存不能用,确保从网络加载最新数据)。
  • no-cache:查找缓存并验证(缓存可用返回304 状态码),缓存不可用重新从网络加载。
  • force-cache:强制使用缓存,如果没有则从网络加载。
  • only-if-cached:只使用缓存,缓存没有则不请求。

示例:

fetch('https://example.com', {
    cache: 'no-cache', // 禁用缓存
});

credentials:控制是否发送 cookies、http认证信息等,常见值有 same-origin 和 include。

  • same-origin:仅在同源请求时自动携带凭证(默认)。
  • include:无论同源还是跨域请求,都携带凭证。
  • omit:请求不携带凭证,适用于公开资源或不需要身份验证的请求。

示例:

fetch('https://example.com', {
    credentials: 'include'
});

发送 GET 请求(fetch)

示例:

fetch('http://127.0.0.1:8080/test?name=123')
    .then(response => response.json())  // 解析 JSON 响应,// 这个 response.json() 不是返回的数据,还要调用 response.json() 函数,等待处理完成返回给下一个 then 才是处理好的数据
    .then(data => {
        console.log(data);  // 输出后台返回的数据
    })
    .catch(error => console.error('Error:', error)); // 错误处理

发送 POST 请求(fetch)

示例:        请求头:Content-Type: application/x-www-form-urlencoded

const data = {
    name: 'Tom'
};
// 将对象转换为 x-www-form-urlencoded 格式
const urlEncodedData = new URLSearchParams(data).toString();

fetch('http://127.0.0.1:8080/test', {
    method: 'POST',
    headers: {
        'Content-Type': 'application/x-www-form-urlencoded',
    },
    body: urlEncodedData,
})
    .then(response => response.json())  // 解析 JSON 响应 // 这个 response.json() 不是返回的数据,还要调用 response.json() 函数,等待处理完成返回给下一个 then 才是处理好的数据
    .then(data => {
        console.log(data);  // 输出后台返回的数据
    })
    .catch(error => console.error('Error:', error)); // 错误处理

示例:        请求头:Content-Type: application/json

fetch('http://127.0.0.1:8080/test', {
    method: 'POST',
    headers: {
        'Content-Type': 'application/json',
    },
    body: JSON.stringify({
        name: 'Tom'
    }),
})
    .then(response => response.json())  // 解析 JSON 响应 // 这个 response.json() 不是返回的数据,还要调用 response.json() 函数,等待处理完成返回给下一个 then 才是处理好的数据
    .then(data => {
        console.log(data);  // 输出后台返回的数据
    })
    .catch(error => console.error('Error:', error)); // 错误处理

处理后台异常响应

fetch 只会在网络失败或请求被阻止时拒绝 Promise。对于 4xx 或 5xx 错误(如 404 或 500),它依然会返回一个 fulfilled (已完成)状态的 Promise,所以需要手动检查 response.ok 来判断请求是否成功。

示例:

fetch('http://127.0.0.1:8080/test?name=123')
    .then(response => {
        // 处理后台程序异常的返回,例如 500
        if (!response.ok) {
            throw new Error('Network response was not ok');
        }
        return response.json();
    })
    .then(data => {
        console.log(data); 
    })
    .catch(error => console.error('Error:', error));

async / await

async / await 是 JavaScript 中用来处理异步操作的一种语法糖,它基于 Promise,使得处理异步代码变得更加简洁和易读。async/await 主要是为了替代 .then() 的链式调用,目的是让异步代码更加简洁和可读。虽然 fetch 本身是异步的,使用 async/await 使得你可以像写同步代码一样处理异步操作,从而避免了嵌套 .then() 造成的“回调地狱”(callback hell)问题

async

async 是一个用于声明异步函数的关键字。它告诉 JavaScript 引擎,这个函数是异步的,返回的结果会是一个 Promise 对象。

当你声明一个 async 函数时,无论函数内部是否有 return,它都会自动返回一个 Promise。如果你在函数内部返回一个值,Promise 会自动将该值包装起来。

语法:

async function foo() {
    // 异步操作
}
console.log(foo());     // 打印 Promise { undefined },表示是一个Promise对象

示例:

// 定义一个 async 函数
async function foo() {
    return "Hello World";
}

// 调用 async 函数,调用 then 函数处理 async 返回结果。
foo().then((result) => {
    console.log(result);
});

await

await 用于等待一个 Promise 对象的结果,它只能在 async 函数内部使用。当遇到 await 时,JavaScript 会暂停 async 函数的执行,等待 Promise 被解析(resolved)或拒绝(rejected)后再继续执行。

没有 await 时: async 函数返回一个 Promise,你需要使用 .then() 或 .catch() 来处理这个 Promise 的结果。
有 await 时: await 会暂停 async 函数的执行,直到 async 函数的返回结果 Promise 被解析,并返回解析的结果给 await。你可以直接在 async 函数内部处理异步结果,而不需要在 async 函数外部使用 .then() 来处理结果了。

示例对比:        // 没用 await 时

async function foo() {
    return "Hello, World!";
}

// 没有 await 时,这样处理 async 的返回结果
foo().then(result => {
    console.log(result);  // 输出: "Hello, World!"
});

示例对比:        // 使用 await 时

async function foo() {
    // 有 await 时,直接在这里等待 async 函数的返回结果,然后在 async 函数内部就把返回结果处理了。
    const result = await "Hello, World!";
    console.log(result);  // 输出: "Hello, World!"
}

foo();

发送 GET 请求(async / await fetch)

示例:

// 创建一个 async 函数
async function get() {
    // 使用 await fetch 发送 GET 请求
    const response = await fetch('http://127.0.0.1:8080/test?name=123');

    // 判断请求后台是否异常
    if (!response.ok) {
        throw new Error('请求失败,状态码:' + response.status);
    }

    const data = await response.json();     // 解析 JSON 响应体,这一步相当于 .then(response => response.json())
    console.log(data);                      // 输出后台返回的数据
}

// 调用 async 函数
get().catch(error => console.error('Error:', error));

发送 POST 请求(async / await fetch)

示例:        请求头:Content-Type: application/x-www-form-urlencoded

// 创建一个 async 函数
async function post() {
    // 请求体的数据,使用 URLSearchParams 对象,创建 x-www-form-urlencoded 数据格式的对象
    const formData = new URLSearchParams();
    formData.append('name', 'Tom');    // 请求参数

    // 使用 await fetch 发送 POST 请求
    const response = await fetch('http://127.0.0.1:8080/test', {
        method: 'POST',     // 设置请求方法为 POST
        headers: {
            'Content-Type': 'application/x-www-form-urlencoded',    // 设置请求头
        },
        body: formData,     // 发送表单数据
    });

    // 判断请求后台是否异常
    if (!response.ok) {
        throw new Error('请求失败,状态码:' + response.status);
    }

    const data = await response.json();     // 解析 JSON 响应体,这一步相当于 .then(response => response.json())
    console.log(data);                      // 输出后台返回的数据
}

// 调用 async 函数
post().catch(error => console.error('Error:', error));

示例:        请求头:Content-Type: application/json

// 创建一个 async 函数
async function post() {
    // 请求参数:一个 JSON 对象
    const requestBody = {
        name: 'Tom'
    };

    try {
        // 使用 await fetch 发送 POST 请求
        const response = await fetch('http://127.0.0.1:8080/test', {
            method: 'POST',     // 设置请求方法为 POST
            headers: {
                'Content-Type': 'application/json',    // 设置请求头
            },
            body: JSON.stringify(requestBody),     // 发送json数据
        });

        // 判断请求后台是否异常
        if (!response.ok) {
            throw new Error('请求失败,状态码:' + response.status);
        }

        const data = await response.json();     // 解析 JSON 响应体,这一步相当于 .then(response => response.json())
        console.log(data);                      // 输出后台返回的数据
    } catch (error) {
        console.error('Error:', error)
    }
}

// 调用 async 函数
post();

Axios

Axios 是一个基于 Promise 的 HTTP 客户端,用于浏览器和 Node.js 环境中发送 HTTP 请求。它支持发送 GET、POST、PUT、DELETE 等常见的 HTTP 请求,并能够处理响应数据。

安装 Axios,这里以 Node.js 环境为例

npm install axios

Axios 的常用方法:

  • axios.get(url [, config]):发送一个 GET 请求。url 是请求的目标 URL,config 是可选的配置对象。
  • axios.post(url [, data [, config]]):发送一个 POST 请求。url 是目标 URL,data 是请求体数据,config 是可选的配置对象。
  • axios.put(url [, data [, config]]):发送一个 PUT 请求。url 是目标 URL,data 是请求体数据,config 是可选的配置对象。
  • axios.delete(url [, config]):发送一个 DELETE 请求。url 是目标 URL,config 是可选的配置对象。
  • axios.head(url [, config]):发送一个 HEAD 请求,通常用于获取响应头信息。url 是目标 URL,config 是可选的配置对象。
  • axios.options(url [, config]):发送一个 OPTIONS 请求,通常用于获取服务器支持的 HTTP 方法。url 是目标 URL,config 是可选的配置对象。
  • axios.patch(url [, data [, config]]):发送一个 PATCH 请求,用于对资源进行部分更新。url 是目标 URL,data 是请求体数据,config 是可选的配置对象。
  • axios.all(iterable):并行发送多个请求,iterable 是一个数组,包含多个 Promise 对象。axios.all() 方法返回一个新的 Promise,在所有请求完成后,才会执行 then 方法。
  • axios.spread(callback):用于 axios.all() 方法返回的多个响应结果展开。它将多个参数分配给传入的回调函数。
  • axios.create([config]):创建一个新的 Axios 实例,可以在实例上设置默认配置,以便复用。
  • axios.CancelToken.source():创建一个取消令牌源,用于取消请求。
  • axios.isCancel(value):检查给定的值是否是由 CancelToken 取消的。

config 常用选项:

headers:设置请求头。用于设置请求发送时携带的头部信息。

示例:

import axios from 'axios';

axios.get('https://api.example.com/data', {
    headers: {
        'Content-Type': 'application/json',
        'Authorization': 'Bearer token_value'
    }
});

params:URL 查询参数,适用于 GET 请求。它会自动被序列化为查询字符串,并追加到 URL 后面。

示例:

import axios from 'axios';

axios.get('https://api.example.com/data', {
    params: {
        userId: 1,
        page: 2
    }
});
// 生成的请求 URL 会是 https://api.example.com/data?userId=1&page=2

timeout:请求的超时时间,单位是毫秒。如果请求超过这个时间没有响应,Axios 会中止请求。

示例:

import axios from 'axios';

axios.get('https://api.example.com/data', {
    timeout: 5000  // 设置超时为5秒
});

auth:设置 HTTP 基本认证凭证,包括 username 和 password。

示例:

import axios from 'axios';

axios.get('https://api.example.com/data', {
    auth: {
        username: 'admin',
        password: '123456'
    }
});

responseType:设置响应的数据类型,常见的值有 json、text、blob、arraybuffer 等。默认是 json。

  • json:响应的数据将会被解析为 JSON 格式,适用于返回 JSON 数据的接口。
  • text:响应的数据将会被处理为纯文本(string),适用于返回文本数据的接口,如 HTML、纯文本内容等。
  • blob:响应的数据会作为 Blob 对象(即二进制大对象)返回,适用于文件下载、图片等二进制数据。
  • arraybuffer:响应的数据会作为 ArrayBuffer 对象返回,通常用于二进制数据流,如音频、视频或其他二进制文件。
  • document:响应的数据将作为 document 对象返回。通常适用于返回 HTML 文档的接口。
  • stream:用于 Node.js 中的请求。stream 使得响应的数据可以作为一个流(stream)处理,通常用于处理大量数据的下载。

示例:

import axios from 'axios';

axios.get('https://api.example.com/data', {
    responseType: 'blob'
});

cancelToken:用于取消请求,提供一个取消令牌,用于在需要时中止请求。

示例:

import axios from 'axios';

const cancelTokenSource = axios.CancelToken.source();
axios.get('https://api.example.com/data', {
    cancelToken: cancelTokenSource.token
});
cancelTokenSource.cancel('请求被用户取消');

withCredentials:是否携带跨域请求时的凭证(如 Cookies)。默认为 false,如果请求跨域且需要凭证,可以设置为 true。

示例:

import axios from 'axios';

axios.get('https://api.example.com/data', {
    withCredentials: true
});

maxRedirects:最大重定向次数,默认情况下 Axios 会自动跟随重定向,设置该参数可以限制最大重定向次数。

示例:

import axios from 'axios';

axios.get('https://api.example.com/redirect', {
    maxRedirects: 5
});

paramsSerializer:一个函数,用于自定义 URL 查询参数的序列化方式。可以用来定制如何将对象转化为查询字符串。

示例:

import axios from 'axios';

axios.get('https://api.example.com/data', {
    params: {
        userId: 1,
        page: 2
    },
    paramsSerializer: function (params) {
        // 使用 URLSearchParams 序列化
        const searchParams = new URLSearchParams(params);
        return searchParams.toString();
    }
});

发送 GET 请求(axios)

示例:

import axios from 'axios';
// 参数在url后面
axios.get('http://127.0.0.1:8080/test?name=123')
    .then(response => {
        console.log(response.data);     // 输出后台返回的数据
    })
    .catch(error => {
        console.error(error);           // 捕获并处理请求中的错误(也可以捕获后台的错误)
    });
import axios from 'axios';
// 参数语法上使用params,实际上还是跟在url后面
axios.get('http://127.0.0.1:8080/test', {
    params: {
        name: 123
    }
})
    .then(response => {
        console.log(response.data);     // 输出后台返回的数据
    })
    .catch(error => {
        console.error(error);           // 捕获并处理请求中的错误(也可以捕获后台的错误)
    });

发送 POST 请求(axios)

示例:        请求头:Content-Type: application/x-www-form-urlencoded

import axios from 'axios';

// 创建 x-www-form-urlencoded 数据格式的对象
const formData = new URLSearchParams();
formData.append('name', 'Tom');    // 请求参数

axios.post('http://127.0.0.1:8080/test', formData, {
    headers: {
        'Content-Type': 'application/x-www-form-urlencoded'    // 不用显式的设置,axios会根据参数的数据类型来选择合适的 Content-Type
    }
})
    .then(response => {
        console.log(response.data);        // 输出后台返回的数据
    })
    .catch(error => {
        console.error(error);              // 捕获前后台的错误
    });

示例:        请求头:Content-Type: application/json

import axios from 'axios';

// 创建 json 对象
const data = {
    name: 'Tom'
};

axios.post('http://127.0.0.1:8080/test', data, {
    headers: {
        'Content-Type': 'application/json'    // 不用显式的设置,axios会根据参数的数据类型来选择合适的 Content-Type
    }
})
    .then(response => {
        console.log(response.data);        // 输出后台返回的数据
    })
    .catch(error => {
        console.error(error);              // 捕获前后台的错误
    });

发送 GET 请求(async / await axios)

import axios from 'axios';

// 定义一个异步函数,使用 async/await 语法
async function get() {
    try {
        // 使用 await 等待 axios.get 请求返回
        const response = await axios.get('http://127.0.0.1:8080/test', { params: { 'name': 123 } });

        console.log(response.data);    // 输出后台返回的数据
    } catch (error) {
        console.error(error);          // 捕获前后台的错误
    }
}

// 调用异步函数
get();

发送 POST 请求(async / await axios)

示例:        请求头:Content-Type: application/x-www-form-urlencoded

import axios from 'axios';

// 定义一个异步函数,使用 async/await 语法
async function post() {
    try {
        // 使用 await 等待 axios.post 请求返回
        const response = await axios.post('http://127.0.0.1:8080/test'
            , new URLSearchParams({ 'name': 'Tom' })    // 创建 x-www-form-urlencoded 数据格式的对象
        );

        console.log(response.data);    // 输出后台返回的数据
    } catch (error) {
        console.error(error);          // 捕获前端和后端的错误
    }
}

// 调用异步函数
post();

示例:        请求头:Content-Type: application/json

import axios from 'axios';

// 定义一个异步函数,使用 async/await 语法
async function post() {
    try {
        // 使用 await 等待 axios.post 请求返回
        const response = await axios.post('http://127.0.0.1:8080/test', { 'name': 'Tom' });

        console.log(response.data);    // 输出后台返回的数据
    } catch (error) {
        console.error(error);          // 捕获前端和后端的错误
    }
}

// 调用异步函数
post();

请求拦截器

请求拦截器(Request Interceptor)允许你在请求被发送到服务器之前,对请求进行修改或添加额外的配置。比如添加认证令牌(token)、设置请求头、统一处理请求参数等。

示例:

import axios from 'axios';

// 请求拦截器
axios.interceptors.request.use(
    (config) => {
        // 在请求发送前做些什么
        // console.log('Request Interceptor:', config);
        config.headers['Authorization'] = `Bearer token`;  // 在请求头中添加 token
        return config;  // 必须返回 config,否则请求不会继续
    },
    (error) => {
        // 对请求错误做些什么
        console.error('Request Error:', error);
        return Promise.reject(error);  // 如果发生错误,继续返回 Promise 错误
    }
);

async function post() {
    try {
        const response = await axios.post('http://127.0.0.1:8080/test', { 'name': 'Tom' });

        console.log(response.data);    // 输出后台返回的数据
    } catch (error) {
        console.error(error);          // 捕获前端和后端的错误
    }
}

// 调用异步函数
post();

响应拦截器

响应拦截器(Response Interceptor)是在收到响应之后、响应数据被 then() 或 catch() 处理之前,对响应数据进行处理的一个功能。响应拦截器允许你在响应结果返回到应用之前,统一处理或修改响应的数据或统一异常错误处理。

示例:

import axios from 'axios';

// 响应拦截器
axios.interceptors.response.use(
    (response) => {
        // console.log('Response Interceptor:', response);  // 在响应数据到达应用之前做些什么

        // TODO 你可以在这里统一处理数据,例如提取其中需要的部分
        console.log("aaaaa", response.data);

        return response.data;  // 只返回响应的主体部分,去掉多余的信息
    },
    (error) => {
        // 对响应错误做些什么
        console.error('Response Error:', error);

        // 例如,如果是 401 错误,可以跳转到登录页面
        if (error.response && error.response.status === 401) {
            window.location.href = '/login';
        }

        return Promise.reject(error);  // 错误处理后,返回拒绝的 Promise
    }
);


async function post() {
    try {
        const data = await axios.post('http://127.0.0.1:8080/test', { 'name': 'Tom' });
        console.log(data);              // 输出后台返回的数据
    } catch (error) {
        console.error(error);          // 捕获前端和后端的错误
    }
}

// 调用异步函数
post();

取消请求

用户可以在页面长时间未返回响应时,点击按钮主动取消请求。前台取消请求后,后台接口仍然还在继续执行(想要后台接口也取消执行,那你需要自定义代码实现,例如再写个取消请求的接口用于前端点击取消是给让前端调用。根据自己的实际情况判断是否需要该需求),只是后续的响应前台不会再处理。axios 也会抛出一个取消的异常供程序员捕获。

示例:

import axios from 'axios';

// 创建一个取消令牌
const CancelToken = axios.CancelToken;
let cancel: (msg?: string) => void; // 用于存储取消函数的变量

async function post() {
    try {
        const response = await axios.post('http://127.0.0.1:8080/test'
            , { 'name': 'Tom' }     // 请求参数
            , {
                cancelToken: new CancelToken(function executor(c) {
                    cancel = c; // 保存取消函数
                })
            }
        );
        console.log(response.data);      // 输出后台返回的数据
    } catch (error) {
        if (axios.isCancel(error)) {
            console.log('请求被取消:', error.message); // 如果请求被取消,会进入这个条件
        } else {
            console.error('请求发生错误:', error); // 其他类型的错误
        }
    }
}

// 调用异步函数
post();

// 假设在某个地方你需要取消请求,这里使用定时器模拟。实际中应该是一个长时间没有返回响应后的一个取消按钮
setTimeout(() => {
    cancel('请求被手动取消'); // 手动取消请求并传递取消的消息
}, 1000); // 1秒后取消请求

中止请求

设置超时时间,当请求超出这个时间限制后,会自动终止请求,并抛出一个超时异常。当然,后台接口依然还是在继续运行。

示例:

import axios from 'axios';

async function post() {
    try {
        const response = await axios.post('http://127.0.0.1:8080/test'
            , { 'name': 'Tom' }
            , {
                timeout: 5000  // 设置超时时间为 5 秒
            }
        );
        console.log(response.data);
    } catch (error: any) {
        // 捕获请求超时错误
        if (error.code === 'ECONNABORTED') {
            console.log('请求超时');
        } else {
            console.error(error);
        }
    }
}

// 调用异步函数
post();


http://www.kler.cn/a/547303.html

相关文章:

  • Linux基础之文件权限的八进制表示法
  • [思考.AI]AI的能力边界?通用与专用模型平衡?人机协作模式?
  • C++的constructor宜翻译为“构造器“,而不是“构造函数“
  • 如果网络中断,Promise.race 如何处理?
  • Qwen2-VL 的重大省级,Qwen 发布新旗舰视觉语言模型 Qwen2.5-VL
  • 笔试题笔记#6 模拟三道题和总结知识
  • AI全栈开发_人工智能AI大模型 Prompt提示词工程详解(全方位介绍及运用)
  • 宝塔和docker的区别
  • C++之线程池(Thread Pool)
  • [MySQL]5-MySQL扩展(分片)
  • OpenMetadata MySQL 数据库使用率提取管道实现解析
  • MATLAB中lookBehindBoundary函数用法
  • AcWing——3722. 骑车路线
  • 【C++】基础入门(详解)
  • flutter image_cropper插件安装后 打包apk 报错命名空间问题
  • ShenNiusModularity项目源码学习(8:数据库操作)
  • Python MutableMapping介绍
  • Jetpack Compose系列教程之(10)——State及remeber
  • LabVIEW袜品压力测试系统
  • yolov8断点续练的时候报错如下