JavaScript fetch发送AJAX请求 作者:马育民 • 2025-01-10 20:37 • 阅读:10010 # 介绍 `fetch` 替代 `XMLHttpRequest`(XHR),可以异步向服务器发送请求,并将响应返回给客户端。 ## fetch VS XHR fetch 和 XMLHttpRequest(XHR) 都是前端与服务器进行数据交互的常用方式,它们各有优缺点 #### API 设计 - fetch 的 API 设计更加 **现代化、简洁和易于使用**,使用起来更加直观和方便 👍 - XHR 的 API 设计比较 **繁琐**,需要进行多个参数的配置和回调函数的处理。 #### 是否基于 Promises - fetch:基于 Promises,代码更加简洁和易读 👍 - XHR:不是基于 Promises #### 错误处理机制 - fetch:更好的处理错误,只在网络错误(如无法连接服务器)时执行 `catch()` 👍 - XHR:根据状态码错误进行处理 #### 支持的数据类型 - 在解析响应数据时,fetch API 提供了多种方法,包括 `.json()`, `.blob()`, `.arrayBuffer()` 👍 - XHR 只支持文本和二进制数据两种数据类型 #### 跨域请求 - 在进行跨域请求时,fetch API 提供了一种简单而强大的解决方案:使用 CORS(跨域资源共享)头部实现跨域请求 👍 - XHR 则使用了一个叫做 XMLHttpRequest Level 2 的规范,在代码编写上相对较为繁琐 #### 支持的请求方法 - fetch API 默认只支持 GET 和 POST 请求方法 - XHR 则支持所有标准的 HTTP 请求方法 👍 #### 请求头部 - 在 fetch 中设置请求头部的方式更加清晰和直接,可以通过 Headers 对象进行设置 👍 - 而 XHR 的方式相对较为繁琐 #### 请求体 - 在发送 POST 请求时,fetch API 要求将请求体数据作为参数传递给 fetch 方法中的 options 对象 - XHR 可以直接在 send() 方法中设置请求体数据 # API ``` fetch(url,options) .then(response => response.json()) // 解析 JSON 数据 .then(data => console.log(data)) // 处理数据 .catch(error => console.error('Error:', error)); // 错误处理 ``` **参数:** - url:要发送请求的目标 URL。 - options(可选):可以指定请求方法(GET、POST 等)、请求头、请求体等内容。 **返回值:** - 返回一个 `Promise` 对象,在请求成功时执行 `then()` ,在请求失败时执行 `catch()` # 例子:发送get请求 ### 成功 ``` ``` 执行结果如下: ![](https://www.malaoshi.top/upload/0/0/1GWNkeZS6dd.png) `res` 是 `Response` 响应对象 ### 失败 发送get请求,url 输入错误,导致 **网络请求失败** **提示:**浏览器控制台如果 **没有报错**,就新打开一个标签页 ``` ``` 报错如下: ![](https://www.malaoshi.top/upload/0/0/1GWNkieXbqs.png) # Response响应对象 ### 获取数据 **注意:**下面方法,返回 `Promise` 对象,在 `then()` 方法中获取数据 - text():将响应体解析为纯文本字符串。 - json():将响应体解析为 JSON 格式并返回一个 JavaScript 对象。 - blob():将响应体解析为二进制数据并返回一个 Blob 对象。 - arrayBuffer():将响应体解析为二进制数据并返回一个 ArrayBuffer 对象。 - formData():将响应体解析为 FormData 对象。 ### 例子-get请求返回 JSON 数据(不推荐) ``` fetch("js/1.json").then( res =>{ console.log("res:",res) // json() 返回 Promise 对象,在 then() 中处理数据 res.json().then( data => { console.log("data:",data) }) }).catch(err => { console.log("err:",err) }) ``` **缺点:**上面写法嵌套使用了 `then()` ### 例子-get请求返回 JSON 数据(推荐) `Promise` 是支持链式调用的,改进上面的写法: ``` fetch("js/1.json").then( res =>{ console.log("res:",res) // 注释下面代码 // res.json().then( data => { // console.log("data:",data) // }) return res.json() // 返回 Promise }).then( data => { // 链式调用上面的返回 Promise console.log("data:",data) }).catch(err => { console.log("err:",err) }) ``` ### 例子-get请求返回 JSON 数据(精简) ``` fetch("js/1.json") .then( res => res.json() ) .then( data => { // 链式调用上面的返回 Promise console.log("data:",data) }).catch(err => { console.log("err:",err) }) ``` # POST 请求 ### 准备 express 服务器 ``` // 引入 express 模块 const express = require('express'); const bodyParser = require('body-parser'); // 创建 express 对象 const app = express(); // 指定监听端口 const port = 8081; // 使用body-parser中间件解析请求体 app.use(bodyParser.urlencoded({ extended: false })); app.use(bodyParser.json()); // 跨域 app.all('*', function(req, res, next) { const origin = req.headers['origin'] res.header("Access-Control-Allow-Origin", origin); res.header("Access-Control-Allow-Headers", "X-Requested-With,Content-Type"); res.header("Access-Control-Allow-Methods","PUT,POST,GET,DELETE,OPTIONS"); next(); }); app.post('/login', (req, res) => { const { username, password } = req.body; console.log(username, password ) // 发送内容 const data = { code: 0, msg: '登录成功!' }; res.json(data); }) app.post('/getUser', (req, res) => { // 发送内容 const data = { code: 0, data: { "name":"李雷", "role":"VIP", "sex":"male" } }; res.json(data); }) // 启动服务,监听端口 const server = app.listen(port, function () { // var host = server.address().address // var port = server.address().port console.log("服务启动成功,监听端口是", port) }) ``` ### 例子-获取数据 获取当前登录人的信息 ``` // 发送 POST 请求 fetch('http://localhost:8081/getUser', { method: 'POST', // 指定请求方法 }) .then(response => response.json()) .then( data => { console.log("data:",data) }).catch(err => { console.log("err:",err) }) ``` ### 例子-携带请求体数据 实现登录 ``` // 发送 POST 请求,携带请求体数据 fetch('http://localhost:8081/login', { method: 'POST', // 指定请求方法 headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ // 携带数据 username: 'lilei', password:'123456' }) }) .then(response => response.json()) .then( data => { console.log("data:",data) }).catch(err => { console.log("err:",err) }) ``` 参考: https://blog.csdn.net/qq_36410795/article/details/131978404 https://www.runoob.com/ajax/fetch-api.html 原文出处:http://malaoshi.top/show_1GWNm3duuVt.html