使用axios及和spirng boot 交互

Axios

Axios是一個基于PromiseHTTP,可以發送getpost等請求,它作用于瀏覽器Node.js中。當運行在瀏覽器時,使用XMLHttpRequest接口發送請求;當運行在Node.js時,使用HTTP對象發送請求。

使用步驟:

? 第一步:安裝axios? 略

第二步:在項目中使用Axios時,通常的做法是先將Axios封裝成一個模塊,然后在組件中導入模塊。

第三步:編寫各種請求?這里只說明 基本的get請求post請求

request({url: '請求路徑',method: 'get',params: { 參數 }
}).then(res => {console.log(res)
}).catch(error => {console.log(error)
})

get請求:

/*** 發送GET請求*/
export const getReq = (url, params) => {return axios({method: 'get',params, // 使用params而非dataurl: `${base}${url}`,headers: {'token': localStorage.getItem("token"),}});
}

?使用它:

// 獲取用戶列表,帶分頁參數
getReq('/api/users', { page: 1, pageSize: 10 }).then(res => {console.log('用戶列表:', res.data);}).catch(err => {console.error('請求失敗:', err);});

?post請求:

request({url: '請求路徑',method: 'post',data: { 參數 }
}).then(res => {console.log(res)
}).catch(error => {console.log(error)
})

export const postReq = (url, params) => {return axios({method: 'post',url: `${base}${url}`,data: params,headers: {'token': localStorage.getItem("token"),}});

??

?異步請求調用中?async+await 的應用

代碼:

export const fetchData = async (url, params) => {try {const response = await axios({method: 'get',params, // 修正:使用 params 而非 dataurl: `${base}${url}`,headers: {'token': localStorage.getItem('token'),}});return response.data;} catch (error) {console.error('請求失敗:', error);throw error; // 修正:重新拋出錯誤,讓調用者處理}
};

?async+await 的概念

async/await 是一種建立在Promise之上的編寫異步或非阻塞代碼的新方法。async 是異步的意思,而 await 是 async wait的簡寫,即異步等待。

所以從語義上就很好理解 async 用于聲明一個 函數 是異步的,而await 用于等待一個異步方法執行完成。

那么想要同步使用數據的話,就可以使用 async+await 。

?說明:async函數返回的是一個 Promise 對象。async 函數(包含函數語句、函數表達式、Lambda表達式)會返回一個 Promise 對象,如果在函數中 ?一個直接量,async 會把這個直接量通過promise.solve() 封裝成 Promise 對象。

如果 async 函數沒有返回值, 它會返回 promise.solve(underfined)。

await 等待的是一個表達式,這個表達式的計算結果是 Promise 對象或者其它值(換句話說,await 可以等任意表達式的結果)。

如果它等到的不是一個 Promise 對象,那 await 表達式的運算結果就是它等到的東西。

如果它等到的是一個 Promise 對象,await 就忙起來了,它會阻塞后面的代碼,等著 Promise 對象 resolve,然后得到 resolve 的值,作為 await 表達式的運算結果。

調用方式:

Promise 鏈式調用:.then().catch() 同步風格的

await:在 async 函數內部使用

  • romise 鏈式調用適合 “非阻塞、并行、兼容舊環境” 的場景,強調異步操作的獨立性。
  • async/await適合 “順序依賴、復雜流程、高可讀性” 的場景,讓異步代碼更接近同步思維模式。
1. 使用?.then()?和?.catch()?鏈式調用
import { fetchData } from './api'; // 假設從 api.js 導入// 調用 fetchData 獲取用戶列表
fetchData('/api/users', { page: 1, pageSize: 10 }).then(data => {console.log('用戶列表:', data);// 處理返回的數據(如更新組件狀態)}).catch(error => {console.error('請求失敗:', error);// 顯示錯誤消息(如彈框提示)});
//其他邏輯會和fetchData同步進行
.....  

2. 在?async?函數內部使用?await

async function loadUsers() {try {// 等待請求完成并獲取數據const data = await fetchData('/api/users', { page: 1, pageSize: 10 });console.log('用戶列表:', data);// 可以直接使用同步風格的代碼處理數據const firstUser = data.list[0];console.log('第一個用戶:', firstUser);} catch (error) {console.error('請求失敗:', error);// 錯誤處理邏輯}
}// 調用 async 函數
loadUsers();

當執行?loadUsers()?函數時,它會返回一個?Promise 對象,并且其內部邏輯會以異步方式執行。以下是詳細解釋:

1. 函數返回值:Promise 對象
  • 原因:任何使用?async?關鍵字聲明的函數都會自動返回一個 Promise。

  • 示例驗證

    javascript

    const result = loadUsers();
    console.log(result instanceof Promise); // 輸出: true
    
  • Promise 的狀態

    • 成功(fulfilled):當?fetchData?請求成功且沒有拋出異常時,Promise 會 resolve,并傳遞?loadUsers?函數的返回值(若沒有顯式返回,默認返回?undefined)。
    • 失敗(rejected):當?fetchData?拋出異常,或?loadUsers?內部?try?塊中的代碼報錯時,Promise 會 reject,并傳遞錯誤對象。
2. 函數執行流程(異步本質)

javascript

console.log('開始執行');
loadUsers();
console.log('結束執行');// 輸出順序:
// 開始執行
// 結束執行
// (等待 fetchData 請求完成后)
// 用戶列表: ...
// 第一個用戶: ...

  • 關鍵特點
    1. loadUsers()?函數被調用后立即返回 Promise,不會阻塞后續代碼執行。
    2. await fetchData(...)?僅暫停函數內部的執行,不會影響外部代碼(如?console.log('結束執行')?會先于?fetchData?的結果輸出)。
    3. 當?fetchData?的 Promise 解決(成功 / 失敗)時,loadUsers?內部的?await?會恢復執行,并決定 Promise 的最終狀態。
3. Promise 的解決(resolve)情況

當?fetchData?請求成功且?try?塊內代碼無異常時:

  • loadUsers?的 Promise 會 resolve,返回值為?undefined(因為函數沒有顯式?return)。

  • 等價于:

    javascript

    async function loadUsers() {// ... 代碼 ...return undefined; // 隱式返回
    }
    
  • 可通過?.then()?捕獲結果

    javascript

    loadUsers().then(result => {console.log('loadUsers 返回值:', result); // 輸出: undefined
    });
    
4. Promise 的拒絕(reject)情況

當出現以下情況時,loadUsers?的 Promise 會 reject:

  1. fetchData?拋出錯誤

    javascript

    fetchData('/api/users', { page: 1 }).catch(error => {throw new Error('請求失敗: ' + error); // 被 loadUsers 的 catch 捕獲});
    
  2. try?塊內其他代碼報錯

    javascript

    const firstUser = data.list[0]; // 若 data.list 為 undefined,會拋出 TypeError
    
  3. catch?塊中重新拋出錯誤

    javascript

    catch (error) {console.error('請求失敗:', error);throw error; // 重新拋出,導致 Promise reject
    }
    

  • 可通過?.catch()?捕獲錯誤

    javascript

    loadUsers().catch(error => {console.error('loadUsers 錯誤:', error);
    });
    
5. 與 Promise 鏈式調用的等價關系

loadUsers?函數的異步邏輯等價于以下 Promise 寫法:

javascript

function loadUsers() {return fetchData('/api/users', { page: 1, pageSize: 10 }).then(data => {console.log('用戶列表:', data);const firstUser = data.list[0];console.log('第一個用戶:', firstUser);// 隱式返回 undefined}).catch(error => {console.error('請求失敗:', error);throw error; // 重新拋出錯誤,保持 Promise 鏈的異常傳遞});
}
6. 如何獲取函數的執行結果?
(1)使用?.then()

javascript

loadUsers().then(() => {console.log('數據處理完成');}).catch(error => {console.error('處理失敗:', error);});
(2)在另一個?async?函數中使用?await

javascript

async function processData() {try {await loadUsers(); // 等待 loadUsers 的 Promise 解決console.log('loadUsers 執行完畢');} catch (error) {console.error('processData 捕獲到錯誤:', error);}
}

  • 返回值loadUsers()?始終返回一個 Promise 對象。
  • 狀態由內部邏輯決定
    • 成功時(fetchData?正常返回且無代碼錯誤):Promise resolve,返回?undefined
    • 失敗時(fetchData?報錯或代碼異常):Promise reject,傳遞錯誤對象。
  • 異步本質:函數內部使用?await?暫僅停自身執行,不阻塞主線程,整體仍為異步操作。

應用transformRequest

export const postRequest = (url, params) => {return axios({method: 'post',url: `${base}${url}`,data: params,transformRequest: [function (data) {let ret = '';for (let key in data) {ret += encodeURIComponent(key) + '=' + encodeURIComponent(data[key]) + '&';}return ret;}],headers: {'Content-Type': 'application/x-www-form-urlencoded', // 修正為表單格式}});
}

說明:

  1. 數據格式與請求頭的關系

    • application/json:請求體應為 JSON 格式(如{"key": "value"})。
    • application/x-www-form-urlencoded:請求體應為表單格式(如key=value&key2=value2)。
  2. transformRequest的影響

    • 當前代碼將對象轉換為表單格式數據,但請求頭卻聲明為 JSON,導致后端可能無法解析。
    • 若后端期望 JSON 數據,應移除transformRequest并保持application/json頭。
  3. 正確的搭配方式

    數據格式Content-Type是否需要 transformRequest
    JSONapplication/json不需要
    表單數據application/x-www-form-urlencoded需要(如當前函數)
    二進制文件 / 表單multipart/form-data不需要

函數調用示例

場景 1:提交表單數據到后端

import { postRequest } from './api.js'; // 導入函數// 表單數據
const formData = {username: 'test_user',password: '123456',email: 'test@example.com'
};// 調用函數
postRequest('/api/register', formData).then(response => {console.log('注冊成功:', response.data);}).catch(error => {console.error('注冊失敗:', error);});
場景 2:發送 JSON 數據(需修改函數)

如果需要發送 JSON 數據,應使用以下封裝:

export const postJsonRequest = (url, params) => {return axios({method: 'post',url: `${base}${url}`,data: params,headers: {'Content-Type': 'application/json',}});
}// 調用示例
const userData = {name: '張三',age: 25,hobbies: ['閱讀', '編程']
};postJsonRequest('/api/users', userData).then(res => console.log(res.data));

調用注意事項

  1. 參數說明

    • url:API 路徑(如/api/login),會自動拼接base(如http://localhost:8080)。
    • params:需要發送的數據對象,會被transformRequest轉換為表單格式。
  2. 錯誤處理

    • 在調用時添加.catch()處理請求失敗:

      postRequest(...).catch(error => {const status = error.response?.status || '網絡錯誤';const message = error.response?.data?.message || '請求失敗';console.error(`狀態碼 ${status}: ${message}`);
      });
      
  3. 與其他請求函數的區別

    • 若后端接口需要不同的 Content-Type,應創建不同的封裝函數(如 JSON 格式、文件上傳等)。

  1. 數據為對象格式(如{key: value}
  2. 后端接口期望表單數據(application/x-www-form-urlencoded
  3. 添加錯誤處理邏輯以應對請求失敗的情況

如果需要發送 JSON 數據,最好創建專門的函數,不需要transformRequest

對不同格式的數據,spring boot 端的處理:

場景推薦注解示例
處理 JSON 數據@RequestBody@RequestBody User user
處理簡單表單數據(少量參數)@RequestParam@RequestParam("username") String name
處理復雜表單數據(對象綁定)@ModelAttribute@ModelAttribute User user
同時支持 JSON 和表單(需自定義)@RequestBody?+ 轉換器配置?FormHttpMessageConverter

建議:

  • JSON:統一使用?@RequestBody,前端發送?application/json
  • 表單:使用?@RequestParam?或?@ModelAttribute,前端發送?application/x-www-form-urlencoded
  • 避免混用:不要試圖用?@RequestBody?同時處理兩種格式,會增加復雜度。

postJsonRequest?

export const postJsonRequest = (url, params) => {return axios({method: 'post',url: `${base}${url}`,data: params,  // axios 自動將對象序列化為 JSONheaders: {'Content-Type': 'application/json',}});
}

?調用方式例子:

// 發送用戶數據
const userData = {username: 'john',email: 'john@example.com',isActive: true
};postJsonRequest('/api/users', userData).then(res => console.log('用戶創建成功:', res.data)).catch(err => console.error('錯誤:', err));

發送表單數據(application/x-www-form-urlencoded)

export const postFormRequest = (url, params) => {return axios({method: 'post',url: `${base}${url}`,data: params,transformRequest: [function (data) {let ret = '';for (let key in data) {ret += encodeURIComponent(key) + '=' + encodeURIComponent(data[key]) + '&';}return ret;}],headers: {'Content-Type': 'application/x-www-form-urlencoded',}});
}

??調用方式例子:

// 提交登錄表單
const loginData = {username: 'admin',password: '123456',rememberMe: true
};postFormRequest('/api/login', loginData).then(res => {localStorage.setItem('token', res.data.token);console.log('登錄成功');}).catch(err => alert('登錄失敗: ' + err.message));

比與適用場景及編碼問題

方案Content-Type數據格式后端適配前端寫法
方案一(JSON)application/json{"key":"value"}Spring Boot 的?@RequestBody直接傳遞對象
方案二(表單)application/x-www-form-urlencodedkey=value&key2=value2Spring Boot 的?@RequestParam/@ModelAttribute需手動或用庫序列化
  1. 后端接口匹配

    • JSON 格式:確保后端使用?@RequestBody?注解
    • 表單格式:確保后端使用?@RequestParam?或?@ModelAttribute
  2. 編碼問題

    • 表單數據中的特殊字符(如中文)會被?encodeURIComponent?自動編碼
    • JSON 數據中的中文會被序列化為 Unicode 字符(如?\u4e2d

putRequest :

export const putRequest = (url, params) => {return axios({method: 'put',url: `${base}${url}`,data: params,transformRequest: [function (data) {if (!data) return '';const ret = [];for (let key in data) {if (data.hasOwnProperty(key)) {const value = data[key];// 處理值為 null 或 undefined 的情況const encodedValue = value === null || value === undefined ? '' : encodeURIComponent(value);ret.push(`${encodeURIComponent(key)}=${encodedValue}`);}}// 使用 join 避免末尾多余的 &return ret.join('&');}],headers: {'Content-Type': 'application/x-www-form-urlencoded'}}).catch(error => {console.error('PUT 請求失敗:', error);// 可以在這里進行統一的錯誤處理throw error; // 繼續拋出錯誤,讓調用者可以捕獲});
};

參考vue+element UI 學習總結筆記(一)_vue+elementui一點-CSDN博客

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/pingmian/85397.shtml
繁體地址,請注明出處:http://hk.pswp.cn/pingmian/85397.shtml
英文地址,請注明出處:http://en.pswp.cn/pingmian/85397.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

布局文件的逐行詳細解讀

總覽 源碼 <?xml version="1.0" encoding="utf-8"?> <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:app="http://schemas.android.com/apk/res-auto&…

VTK 顯示大量點云數據及交互(點云拾取、著色、測量等)功能

VTK (Visualization Toolkit) 是一個強大的開源可視化庫&#xff0c;非常適合處理點云數據。下面將介紹如何使用 VTK 顯示大量點云數據&#xff0c;并實現點云拾取、著色、測量等功能。 基本點云顯示 創建一個基本的點云顯示程序&#xff1a; cpp #include <vtkSmartPoi…

性能優化 - 高級進階: 性能優化全方位總結

文章目錄 Pre1. 概述&#xff1a;性能優化提綱與使用場景2. 準備階段2.1 明確優化范圍與目標2.2 環境與工具準備 3. 數據收集與指標確認3.1 關鍵資源維度與指標項3.2 監控體系搭建與初始采集3.3 日志與追蹤配置 4. 問題定位思路4.1 從整體到局部的分析流程4.2 常見瓶頸維度檢查…

Mybatis之Integer類型字段為0,入庫為null

背景&#xff1a; 由于項目某個功能用到優先級字段來判斷&#xff0c;需要在mysql表中定義一個字段XX&#xff0c;類型為int&#xff0c;默認為0&#xff0c;具體值由后臺配置&#xff0c;正常入庫即可 問題&#xff1a; 由于后臺配置存量其他類型的數據無需該字段&#xff0c…

上海市計算機學會競賽平臺2022年3月月賽丙組洗牌

題目描述 給定一個整數 nn&#xff0c;表示 nn 張牌&#xff0c;牌的編號為 11 到 nn。 再給定一個洗牌置換 f1,f2,…,fnf1?,f2?,…,fn?&#xff0c;進行一次洗牌操作時&#xff0c;應將第一號位置的牌交換到第 f1f1? 號位置&#xff0c;將第 ii 號位置的牌交換到第 fifi…

DINO-R1:激勵推理能力的視覺基礎模型

摘要 近期&#xff0c;人們對大型語言模型&#xff08;如DeepSeek-R1&#xff09;推理能力的關注呈爆炸式增長&#xff0c;通過基于強化學習的微調框架&#xff08;如組相對策略優化&#xff08;Group Relative Policy Optimization&#xff0c;GRPO&#xff09;方法&#xff…

Linux--LVM邏輯卷擴容

Linux–LVM邏輯卷擴容 文章目錄 Linux--LVM邏輯卷擴容?? LVM 常用命令分類及基本格式? 1. 物理卷(PV)相關命令? 2. 卷組(VG)相關命令? 3. 邏輯卷(LV)相關命令?? 三、查看類命令簡寫說明使用命令及基本格式:lvm邏輯卷擴容步驟:1.添加硬盤設備2.檢測新增硬盤 添加…

C#基礎語法與控制臺操作

1. 控制臺操作基礎 控制臺程序是學習C#的起點。以下是一些常用的控制臺操作方法&#xff1a; 1.1. 清除控制臺 Console.Clear(); // 清除控制臺內容1.2. 輸出字符串 Console.WriteLine("Hello World!"); // 在屏幕的當前位置換行輸出字符串 Console.Write("…

100.Complex[]同時儲存實數和虛數兩組double的數組 C#例子

在信號處理中&#xff0c;IQ 數據&#xff08;In-phase and Quadrature&#xff09;通常表示復數形式的信號&#xff0c;其中實部表示同相分量&#xff0c;虛部表示正交分量。Complex[] data 是一個包含 IQ 數據的數組&#xff0c;每個元素是一個復數&#xff0c;表示一個信號樣…

停止追逐 React 重渲染

大多數開發者都在浪費時間對抗多余的重渲染。真正的 React 架構師根本讓問題無從產生——下面就來揭開他們的思路&#xff0c;以及為何大多數所謂的性能優化技巧反而拖慢了你的應用。 重渲染的無盡輪回 先來直擊痛點&#xff1a;如果還在項目里到處撒 useMemo、useCallback&…

流水線的安全與合規 - 構建可信的交付鏈

流水線的安全與合規 - 構建可信的交付鏈 “安全左移 (Shift-Left Security)”的理念 “安全左移”是 DevSecOps 的核心理念,指的是將安全測試和考量,從軟件開發生命周期 (SDLC) 的末端(發布前),盡可能地向左移動到更早的階段(如編碼、構建、測試階段)。 為何對 SRE 至…

???????神經網絡基礎講解 一

??一.神經網絡 ? ??1. 全連接神經網絡&#xff08;Fully Connected Network, FCN&#xff09;?? ??核心概念&#xff1a;?? ??輸入層??&#xff1a;接收原始數據&#xff08;如數字、圖片像素等&#xff09; 數字矩陣 。??隱藏層??&#xff1a;對數據…

MySQL 8.0 OCP 英文題庫解析(二十二)

Oracle 為慶祝 MySQL 30 周年&#xff0c;截止到 2025.07.31 之前。所有人均可以免費考取原價245美元的MySQL OCP 認證。 從今天開始&#xff0c;將英文題庫免費公布出來&#xff0c;并進行解析&#xff0c;幫助大家在一個月之內輕松通過OCP認證。 本期公布試題201~210 試題2…

【大模型推理】PD分離場景下decoder負載均衡,如何選取decoder

https://mp.weixin.qq.com/s?__bizMzg4NTczNzg2OA&mid2247507420&idx1&sn4b32726abd205c7f94144bcb9105330f&chksmce64b9fc7f1d8de04a40b0153302dee52262c6f104c67195e2586e75c8093b8be493f252c8a3#rd 在非 Local 場景下&#xff0c;Prefill 定時獲取 Decode …

【IP地址】IP應用場景的使用方向

網絡安全領域 通過IP地址查詢&#xff0c;安全系統能夠實時監控網絡流量&#xff0c;識別異常訪問行為。例如&#xff0c;當某個IP地址在短時間內頻繁發起大量請求&#xff0c;且訪問模式與正常用戶存在明顯差異時&#xff0c;系統可將其標記為可疑IP&#xff0c;觸發風險預警…

3-18 WPS JS宏 顏色設置實例應用(按條件設置單元格顏色)學習筆記

前面講解了關于單元格的一些格式的設置&#xff0c;本節課再講解一下各種清除方法。 1.函數解析與用法 Range().clear()//清除全部 Range().Value2null //清除內容 Range().ClearContents()//清除內容 Range().ClearFormats()//清除格式 Range().EntireRow.Range()//以Ra…

從零開始的云計算生活——第二十天,腳踏實地,SSH與Rsync服務

目錄 一.故事背景 二.SSH帶外管理 1.概述 2. 配置文件 3.命令解析 4.登錄方式配置 a.用戶名密碼登錄 b.公鑰驗證登錄 5.實操生成密鑰對 三.Rsyncsersync實現數據實時同步 1.rsync概述 2.rsync運行原理 3.rsync部署 4.備份測試 配置備份目錄 5.rsyncsersync 實現…

SpringAI + DeepSeek大模型應用開發 - 初識篇

一、認識AI 1. AI的發展 AI&#xff0c;人工智能&#xff08;Artificial Intelligence&#xff09;&#xff0c;使機器能像人類一樣思考、學習和解決問題的技術。 2. 大模型及其原理 在自然語言處理&#xff08;Natural Language Processing, NLP&#xff09;中&#xff0c;…

c++第八天-多態

虛函數虛析構函數純虛函數與抽象類 多態實現的條件&#xff1a;&#xff08;1&#xff09;公有繼承 &#xff08;2&#xff09;派生類重寫基類虛函數 &#xff08;3&#xff09;基類指針/引用指向派生類對象 虛函數不能是構造函數&#xff0c;不能是靜態函數&#xff0c;不能…

全景圖渲染Vue3+TS使用Photo Sphere Viewer插件實現

1.Photo Sphere Viewer插件安裝: title=插件安裝 體驗AI代碼助手 代碼解讀復制代碼npm install photo-sphere-viewer -S 或 yarn add photo-sphere-viewer -S 2.原始全景圖展示 初始化標簽容器 體驗AI代碼助手 代碼解讀復制代碼 // 全景圖的根節點必須要具備寬高 TS引用,創建…