快速搭建服務器,fetch請求從服務器獲取數據

?1.strapi

? ? ? ? 首先strapi是一個api管理系統,可以讓我們直接用網頁的形式去定義自己的api,包括設置模型和權限等功能。

? ? ? ? 首先直接在項目目錄里面安裝庫。npx create-strapi@latest server --quickstart這樣就可以直接在項目目錄創建一個連接數據庫的服務器了。不用我們去書寫代碼,直接在網頁版數據庫添加表以及表中的數據就可以自動生成api讓我們去訪問請求了。

????????

? ? ? ? 就是這種,我們網頁形式創建表,添加權限,自動生成api。這樣我們就可以在前端發送請求去獲取數據了。值得一提的是記得npm的版本以及node.js版本會有限制。

? ? ? ? 可以裝一個nvm管理自己開發項目用的node。

? ? ? ? 我是mac系統所以用brew安裝nvm brem install nvm,然后創建nvm工作目錄 mkdir ~/.nvm

然后配置終端環境變量,nano ~/.zshrc 然后文件內容

Maestro CLI
export PATH="$HOME/.maestro/bin:$PATH"OpenJDK 17
export PATH="/opt/homebrew/opt/openjdk@17/bin:$PATH"nvm 配置(Homebrew 路徑,Apple M 芯片)
export NVM_DIR="$HOME/.nvm"
[ -s "/opt/homebrew/opt/nvm/nvm.sh" ] && \. "/opt/homebrew/opt/nvm/nvm.sh"
[ -s "/opt/homebrew/opt/nvm/etc/bash_completion.d/nvm" ] && \. "/opt/homebrew/opt/nvm/etc/bash_completion.d/nvm"

? ? ? ? 然后control x退出 按y 再按回車保存退出成功。在執行立即生效命令 source ~/.zshrc這樣nvm就配置好了。我們用nvm install 22裝上 22版本的node.js然后nvm use 22就可以創建strapi項目了。

2.fetch?

? ? ? ? ?上面網頁可以看到我們路由是/api/students,那么我們就可以嘗試去用fetch(瀏覽器自帶的發送請求的api,是瀏覽器提供的全局函數,返回的一個promise)所以可以用鏈式調用.then.catch因為promise有狀態,請求成功自動執行.then失敗會自動調用.catch而且參數就是返回的promise實例對象。

import React, { useEffect } from 'react'export default function App() {const [person, setPerson] = React.useState([])const [show, setShow] = React.useState(false)/*從接口http://localhost:1337/api/students中加載數據組件一渲染就向服務器發送請求加載數據組件初始化時候發送請求來加載數據*/useEffect(() => {//說明數據開始加載了setShow(true)//發送請求//fetch()用來向服務器發送請求加載數據,Ajax的升級版//需要兩個參數 1.請求地址2.請求信息//promise兩個特點 成功和失敗兩個回調函數.then成功時候調用 .catch失敗時調用fetch('http://localhost:1337/api/students/').then((res) => {//response表示響應信息// console.log(res);return res.json();//該方法可以將響應的json直接轉換為js對象}).then((data) => {console.log(data.data);// 將加載到的數據設置進state中setPerson(data.data)setShow(false)}).catch(() => { })}, [])return (<div>{show ? (<p>正在加載中...</p>) : (person.map((item) => (<div key={item.id}>{item.name} --- {item.gender} --- {item.age}</div>)))}</div>)
}

? ? ? ? 這里我們沒有寫fetch發送請求的類型,所以是get。這里展示數據成功,說明訪問成功之后把數據返回來了,但是第一次是json類型

????????

????????我們需要去轉化成對象。比如這里再次使用.then是因為前面的.then把json轉化為js對象。然后return返回的也是一個promise實例對象。所以可以.then,報錯.catch捕捉。?

????????

? ? ? ? 這里轉化的js對象有兩個屬性一個是data,一個是meta(不認識),但是我們展開確定我們需要的是data里面的對象?

? ? ? ? 所以用setState去存住返回來的數據就可以去展示到頁面上面了。就實現了第一次用fetch請求api響應數據展示的過程了。

? ? ? ? 但是我們要知道還有一個.catch我們沒有去寫,比如我們去掉路由students中的s,

?

?

? ? ? ? 返回404但是問題是map也就是map方法錯了所以請求整個過程還是執行了?這很明顯不對。但是我們看到ok變為false,那么我們就可以去截斷這個請求過程。而且statusText都變了。

????????

? ? ? ? 對比我們就知道如果錯了,ok和statueText會改變,那就對這些進行判斷。

?????????

? ? ? ? 比如這里,這樣如果錯誤就不會再執行請求后面的代碼了。因為只有成功才會返回promise實例對象,才可以調用后面的.then,而且.catch沒有內容所以什么都沒有。

import React, { useEffect } from 'react'export default function App() {const [person, setPerson] = React.useState([])const [show, setShow] = React.useState(false)const [err, setError] = React.useState(null)/*從接口http://localhost:1337/api/students中加載數據組件一渲染就向服務器發送請求加載數據組件初始化時候發送請求來加載數據*/useEffect(() => {//說明數據開始加載了setShow(true)//發送請求//fetch()用來向服務器發送請求加載數據,Ajax的升級版//需要兩個參數 1.請求地址2.請求信息//promise兩個特點 成功和失敗兩個回調函數.then成功時候調用 .satch失敗時調用fetch('http://localhost:1337/api/students/').then((res) => {//判斷是否正常返回響應信息if (res.ok) {console.log(res);return res.json()}//代碼運行到這里 說明沒有加載到數據// setShow(false)//拋出一個錯誤throw new Error('數據加載失敗')// response表示響應信息// console.log(res);// return res.json();//該方法可以將響應的json直接轉換為js對象}).then((data) => {// console.log(data);// 將加載到的數據設置進state中setPerson(data.data)setShow(false)}).catch((e) => {//catch中的回調函數用來統一處理錯誤//catch執行說明上面代碼出錯setShow(false)// console.log(e);console.log('e', e)setError(e)})}, [])return (<div>{show && <p>加載中</p>}{err && <p>出錯了:{err.message}</p>}{!show && !err && person.map((item) => (<div key={item.id}>{item.name} --- {item.gender} --- {item.age}</div>))}</div>)
}

? ? ? ? 當報錯的時候用throw new Error(‘’)扔出一個err,然后.catch就可以捕捉到。這樣就完成了整個請求的邏輯,首先要有一個state接收響應數據,還要有一個state去控制請求發送后如果沒有即使響應展示的內容,還需要一個state去控制頁面如果報錯了展示錯誤信息,

3.async await語法糖

import React, { useEffect } from 'react'export default function App() {const [person, setPerson] = React.useState([])const [show, setShow] = React.useState(false)const [err, setError] = React.useState(null)useEffect(() => {const fetData = async () => {try {setShow(true)setError(null)const res = await fetch('http://localhost:1337/api/students')if (res.ok) {const data = await res.json()setPerson(data.data)} else {throw new Error('數據加載失敗!')}} catch (e) {setError(e)} finally {setShow(false)}}fetData()}, [])return (<div>{show && <p>加載中</p>}{err && <p>出錯了:{err.message}</p>}{!show && !err && person.map((item) => (<div key={item.id}>{item.name} --- {item.gender} --- {item.age}</div>))}</div>)
}

? ? ? ? ?

????????最開始我們使用 fetch 是通過連續調用 .then 來一步步獲取 response 和 json 數據,因為 fetch 返回的是一個 Promise 實例對象,不能直接取到里面的數據。而使用 await 關鍵字后,就相當于自動幫我們調用了 .then,把 Promise 解析后的數據直接賦值給變量。比如第一次用 await fetch... 獲取響應對象 response,第二次再用 await response.json() 把 JSON 數據解析成 JS 對象。

????????由于 await 是同步語法風格,我們就不能再用 .catch 來捕獲錯誤,而需要使用 try catch finally 來捕獲異常,比如 throw 拋出的錯誤才能在 catch 中處理。需要注意的是:只有在 async 聲明的函數中才能使用 await。

4.刪除數據

import React, { } from 'react';
import StuContext from './store/StuContext';
import StudentForm from './StudentForm';
const Student = (props) => {const Stx = React.useContext(StuContext)const [loading, setLoading] = React.useState(false)const [error, setError] = React.useState(null)const [isEdit, setIsEdit] = React.useState(null)const deleteData = React.useCallback(async () => {try {setLoading(true)setError(null)const res = await fetch(http://localhost:1337/api/students/${props.stu.documentId}, {method: 'delete'})if (!res.ok) {throw new Error('刪除失敗')}//修改成功后觸發列表重新刷新Stx.fetchData()// const data = await res.json()// console.log('data', data)// 被刪除的學生} catch (e) {console.log(e);setError(e)} finally {setLoading(false)}}, [])const Delete = () => {//刪除學生deleteData()}const cancel = () => {setIsEdit(false)}return (<>{!isEdit &&<tr><td>{props.stu.name}</td><td>{props.stu.gender}</td><td>{props.stu.age}</td><td>{props.stu.address}</td><td><button onClick={Delete} >刪除</button></td><td><button onClick={() => { setIsEdit(true) }} >修改</button></td></tr>}{isEdit && <StudentForm stu={props.stu} onCancel={cancel} />}{loading && <tr><td colSpan={5}>正在刪除數據</td></tr>}{error && <tr><td colSpan={5}>刪除失敗</td></tr>}</>);
};export default Student;

? ? ? ? 這是我們的刪除請求,我們只需要在后面的對象中指名請求頭為delete就可以去刪除了。當然需要一個參數documentId去指名刪除的哪一個。id不行在說一邊我用的strapi不支持id去指定刪除或者更新的表中的列。卡了一天了.............只不過一個點是Context我們用到了,因為我們

?????????

?

? ? ? ? 每次在刪除之后需要重新加載一遍數據,保證最新的數據在 頁面上。

     <StuContext.Provider value={{ fetchData }}><div className="app"><button onClick={() => { loadDataHandler() }}>加載數據</button>{(!loading && !error) && <StudentList stus={stuData} />}{loading && <p>數據正在加載中...</p>}{error && <p>數據加載異常!</p>}</div></StuContext.Provider>

? ? ? ? 就是這樣然后我們在刪除請求成功之后,執行一下重新加載的方法就好了。

5.創建以及更新請求

import React from 'react'
import './StudentForm.css'
import StuContext from './store/StuContext'
export default function StudentForm(props) {const Stx = React.useContext(StuContext)const [input, setInput] = React.useState({name: props.stu ? props.stu.name : '', age: props.stu ? props.stu.age : '',address: props.stu ? props.stu.address : '', gender: props.stu ? props.stu.gender : '男'})const [loading, setLoading] = React.useState(false)const [err, setErr] = React.useState(null)const addData = (async (input) => {try {setLoading(true)setErr(null)const res = await fetch('http://localhost:1337/api/students', {method: 'post',body: JSON.stringify({data: input}),headers: {'Content-Type': 'application/json'}})console.log('res.ok', res.ok)if (!res.ok) {throw new Error('添加失敗')}//添加成功刷新列表Stx.fetchData()} catch (e) {console.log(e);setErr(e)} finally {setLoading(false)}})const updataData = (async (newStu, id) => {try {setErr(null)setLoading(true)const res = await fetch(http://localhost:1337/api/students/${id}, {method: 'PUT',body: JSON.stringify({ data: newStu }),headers: {'Content-Type': 'application/json'}})if (!res.ok) {throw new Error('修改出錯')}Stx.fetchData()} catch (e) {setErr(e)} finally {setLoading(false)}})const nameChange = (e) => {setInput((preState) => ({ ...preState, name: e.target.value }))}const ageChange = (e) => {setInput((preState) => ({ ...preState, age: +e.target.value }))}const genderChange = (e) => {setInput((preState) => ({ ...preState, gender: e.target.value }))}const addressChange = (e) => {setInput((preState) => ({ ...preState, address: e.target.value }))}const handle = () => {addData(input)}const updataHandle = () => {updataData(input, props.stu.documentId)}return (<><tr className='student-form'><td><input type="text" onChange={nameChange} value={input.name} /></td><td><select name="" id="" onChange={genderChange} value={input.gender}><option value="男">男</option><option value="女">女</option></select></td><td><input type="text" onChange={ageChange} value={input.age} /></td><td><input type="text" onChange={addressChange} value={input.address} /></td><td>{props.stu && <><button onClick={() => { props.onCancel() }}>取消</button><button onClick={updataHandle}>修改</button></>}{!props.stu && <button onClick={handle}>添加</button>}</td></tr>{loading && <tr><td colSpan={5}>添加中</td></tr>}{err && <tr><td colSpan={5}>添加失敗</td></tr>}</>)
}

? ? ? ? 唯一不同的是我們在執行創建或者更新請求除了請求頭不同以外,創建也就是添加新表元素需要傳一個json格式的文本內容,也就是我們需要把js對象轉化成json格式。正好對應我們響應體json格式需要轉化成js對象我們用。以及指明請求體的格式,headers:{“Content-Type:'application/json'”}說明我們傳過去的是json格式。包括更新,畢竟我們是傳過去數據而不是get獲取數據。這一點要注意。好了現在我們用fetch實現了post 增 delete刪 put 改 get查了。雖然不熟練但至少有個思路怎么去數據庫拿東西了。至于優化還是慢慢來吧。

?????????

?

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

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

相關文章

UGF開發記錄_3_使用Python一鍵轉換Excle表格為Txt文本

使用UnityGameFramework日常記錄_3_配一鍵轉換配置表 該系列只做記錄 不做教程 所以文章簡潔直接 會列出碰到的問題和解決方案 只適合UGF萌新 為了提高效率&#xff0c;我使用Python編寫了一個腳本&#xff0c;實現了一鍵將Excel表格批量轉換為帶分隔符的Txt文件&#xff0c…

leetcode 3440. 重新安排會議得到最多空余時間 II 中等

給你一個整數 eventTime 表示一個活動的總時長&#xff0c;這個活動開始于 t 0 &#xff0c;結束于 t eventTime 。同時給你兩個長度為 n 的整數數組 startTime 和 endTime 。它們表示這次活動中 n 個時間 沒有重疊 的會議&#xff0c;其中第 i 個會議的時間為 [startTime[i]…

大型語言模型(LLM)的最新研究進展及相關新信息技術

大型語言模型(LLM)的最新研究進展及相關新信息技術 一、Google的Gemini 2.0系列 1. Gemini 2.0 Flash Thinking 核心技術:引入“推理時計算”(Inference-Time Computation)機制,支持模型在回答復雜問題前自主“思考”,顯著提升數學和代碼任務的準確性。多模態能力:支…

c++-友元函數和友元類

友元友元提供了一種突破封裝的方式&#xff0c;有時提供了便利。但是友元會增加耦合度&#xff0c;破壞了封裝&#xff0c;所以 友元不宜多用。 友元分為&#xff1a;友元函數和友元類友元函數問題現在嘗試去在Date類里重載operator<<。無論怎樣設置參數&#xff0c;只要…

alpinelinux的網絡配置

在 Alpine Linux 中配置網絡&#xff0c;您可以根據以下步驟進行&#xff1a; 配置本機 hostname&#xff1a; 本機hostname保存在/etc/hostname文件中。 echo alpine-web > /etc/hostname hostname -F /etc/hostname # 立即生效運行結果&#xff1a; localhost:~# echo &qu…

day1--項目搭建and內容管理模塊

1. 項目搭建1.1 創建父工程1.1.1 創建xuecheng-plus-project工程1.1.2 導入依賴<?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0" xmlns:xsi"http://www.w3.org/2001/XMLSchema-instan…

騰訊云錄音文件快速識別實戰教程

文章目錄前言接口簡介前置條件實戰添加 Maven 依賴核心代碼示例參數說明個人簡介前言 本文介紹如何基于騰訊云語音識別 快速識別接口&#xff0c;實現通過 HTTPS POST 方式上傳音頻并快速識別同步返回識別結果的實戰流程。 接口簡介 騰訊云語音識別 快速識別接口 支持上傳音…

.NET Framework 安裝失敗及異常情況 常用處理方法

在使用.NET Framework 的過程中&#xff0c;安裝失敗或出現異常是比較常見的問題。這些問題可能由系統環境、文件損壞、權限不足等多種原因引起。以下是一些常見的安裝失敗及異常情況&#xff0c;以及對應的處理方法&#xff1a; 首先&#xff0c;下載.net framework 3.5文件。…

?AI賦能的自動駕駛革命:從安全架構到世界模型的系統性突破

?在計算機視覺與機器人技術的交匯處&#xff0c;自動駕駛正經歷著從模塊化設計向端到端AI系統的范式轉移。NVIDIA作為這場變革的核心推動者&#xff0c;其DRIVE平臺展現出的技術整合深度令人驚嘆——從芯片級的能效優化到城市級數字孿生仿真&#xff0c;構建起覆蓋"AI訓練…

ACL協議:核心概念與配置要點解析

ACL協議 在H3C網絡設備&#xff08;交換機、路由器、防火墻等&#xff09;中&#xff0c;ACL&#xff08;Access Control List&#xff0c;訪問控制列表&#xff09; 是一個核心的流量過濾和控制機制。核心目的&#xff1a; 流量過濾&#xff1a;控制哪些流量可以通過接口&…

文件追加模式:編寫一個程序,向一個已存在的文件末尾追加內容。

知識點文件打開模式"r"&#xff1a;只讀&#xff1b;文件須存在。"w"&#xff1a;寫入&#xff1b;清空或新建。"a"&#xff1a;追加&#xff1b;文件末尾寫入。"a"&#xff1a;讀/寫追加。追加&#xff08;Append&#xff09;機制&qu…

OneCode框架事件基礎模型架構深度剖析與代碼實現

一、整體架構概覽 作為OneCode框架的事件核心模塊&#xff0c;構建了一套跨瀏覽器、多終端兼容的事件驅動架構。該架構采用分層設計思想&#xff0c;從底層事件捕獲到高層事件模擬&#xff0c;形成了完整的事件生命周期管理體系。整體架構可分為五個核心層次&#xff1a;事件捕…

Spring for Apache Pulsar->Reactive Support->Message Production

好消息&#xff1a;Spring for Apache Pulsar這兩天剛剛升到2.0.0版本1. ReactivePulsarTemplate在Pulsar生產者端&#xff0c;Spring Boot自動配置提供了一個ReactivePulsarTemplate用于發布記錄。該模板實現了一個名為ReactivePulse Operations的接口&#xff0c;并提供了通過…

AtCoder Beginner Contest 413

比賽鏈接如下&#xff1a;Denso Create Programming Contest 2025&#xff08;AtCoder Beginner Contest 413&#xff09; - AtCoder A - Content Too Large Problem Statement Takahashi has N items and one bag. The size of the i-th (1≤i≤N) item is Ai?, and the si…

Java學習---JVM(1)

JVM&#xff0c;即Java虛擬機&#xff0c;其是Java程序的運行環境&#xff0c;是Java技術的核心組成部分&#xff0c;本次就JVM的自動內存管理詳細展開&#xff1a;JVM的內存區域分為2大類&#xff0c;即線程私有的和線程共享的&#xff0c;前者分為3大塊&#xff0c;虛擬機棧、…

Qt去噪面板搭建

建立單選互斥性面板用于選擇噪聲屬性// 創建去噪面板 QWidget* noisePanel new QWidget(); QVBoxLayout* mainLayout new QVBoxLayout(noisePanel); mainLayout->setContentsMargins(10, 10, 10, 10); mainLayout->setSpacing(15);// 去噪方法選擇組QGroupBox* methodG…

無需公網IP的文件交互:FileCodeBox容器化部署技術解析

文章目錄 前言1.Docker部署2.簡單使用演示3. 安裝cpolar內網穿透4. 配置公網地址5. 配置固定公網地址 前言 在數字化辦公需求日益增長的今天&#xff0c;文件傳輸已成為職場協作的高頻剛需。傳統共享方式卻飽受詬病&#xff1a;"需要安裝哪些臃腫客戶端&#xff1f;免費版…

1. http 有哪些版本,你是用的哪個版本,怎么查看

http 有哪些版本&#xff0c;你是用的哪個版本&#xff0c;怎么查看 總結&#xff1a;http 版本有 0.9/1.0/1.1/2.0/3.0&#xff0c;我們常用的是 1.1 和 2.0&#xff0c;使用 window.chrome.loadTimes() 獲取 http 版本。 常見的 HTTP 版本 HTTP/0.9&#xff1a;最初的版本&am…

C# IIncrementalGenerator干點啥

生成器項目 得基于.Net Stander 2.0 重要&#xff1a;<IsRoslynComponent>true</IsRoslynComponent>、<IncludeBuildOutput>false</IncludeBuildOutput>、 <PackageReference Include"Microsoft.CodeAnalysis" Version"4.14.0&q…

在徐州網絡中服務器租用與托管的優勢

一、高性價比&#xff1a;徐州萬恒提供多種配置的服務器供租用&#xff0c;滿足不同企業和個人的業務需求&#xff0c;無論是初創企業追求低成本高效能&#xff0c;還是對性能有嚴苛要求的大型項目&#xff0c;都能找到合適的服務器型號&#xff0c;以極具競爭力的價格獲取強大…