最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

React + Node.js實(shí)現(xiàn)圖片上傳功能

 更新時(shí)間:2024年01月12日 09:32:57   作者:JacksonChen_  
最近筆者在開發(fā)個(gè)人博客的后臺(tái)管理系統(tǒng),里面用到了圖片上傳相關(guān)的功能,在這里記錄并分享一下,希望可以幫到大家,話不多說直接開始吧,感興趣的朋友可以參考下

效果

技術(shù)棧

前端:react+antdesign(upload組件)

后端:node+express+multer+uuid

前端

上傳前

這邊前端直接使用的 antdesign 所提供的上傳組件,代碼如下

       <Upload
              accept="multipart/form-data"
              name="avater"
              listType="picture-card"
              fileList={[]} // 手動(dòng)設(shè)置空的 fileList
              className="avatar-uploader"
              showUploadList={false}
              beforeUpload={(file) => {
                handlePreview(file)
                return false // 阻止默認(rèn)上傳行為
              }}
            >
              {imageUrl ? <img src={imageUrl} alt="avater" style={{ width: '100%' }} /> : uploadButton}
            </Upload>

accept="multipart/form-data:是用于指定在 HTML 表單中上傳文件時(shí)使用的編碼類型。它告訴服務(wù)器將表單數(shù)據(jù)編碼為 multipart/form-data 格式,這是用于上傳文件的一種常見方式。

beforeUpload:則是需要在上傳前對(duì)文件進(jìn)行處理,我們來看一下代碼里面發(fā)生了什么。

  const handlePreview = async (file: File) => {
    setImageUrl('')
    setLoading(true)
    const isImage = file.type.startsWith('image/')
    const isImageExtension = /\.(jpg|jpeg|png|gif)$/i.test(file.name)
 
    if (!isImage || !isImageExtension) {
      message.error(`${file.name} is not a supported image file`)
      return Upload.LIST_IGNORE
    }
 
    try {
      const reader = new FileReader()
      reader.onload = () => {
        setImageUrl(reader.result as string)
        setLoading(false)
      }
      reader.readAsDataURL(file)
    } catch (error) {
      console.error('圖片預(yù)覽失敗', error)
      message.error('圖片預(yù)覽失敗')
      setLoading(false)
    }
  }

首先判斷文件的格式是不是圖片類型的,如果不是,則終止上傳。

    const isImage = file.type.startsWith('image/')
    const isImageExtension = /\.(jpg|jpeg|png|gif)$/i.test(file.name)
 
    if (!isImage || !isImageExtension) {
      message.error(`${file.name} is not a supported image file`)
      return Upload.LIST_IGNORE
    }

如果是圖片類型則創(chuàng)建一個(gè)新的FileReader對(duì)象。

reader.readAsDataURL(file) 開始讀取指定的文件,這里的 file 是一個(gè)文件對(duì)象,通過某種方式傳遞給這段代碼。readAsDataURL方法會(huì)將文件內(nèi)容讀取為Data URL。

reader.onload設(shè)置一個(gè)事件處理程序,當(dāng)文件讀取完成時(shí)會(huì)觸發(fā)該事件。

在讀取完成時(shí),觸發(fā) onload 事件。在這個(gè)函數(shù)中,通過 reader.result 獲取讀取到的Data URL,然后使用 setImageUrl 函數(shù)將其反顯到頁面當(dāng)中。

    const reader = new FileReader()
      reader.onload = () => {
        setImageUrl(reader.result as string)
        setLoading(false)
      }
      reader.readAsDataURL(file)

這段上傳前的代碼是為了判斷是否為圖片類型,以及讀取出來圖片反顯到頁面當(dāng)中,大家根據(jù)自己的需求調(diào)整。

反顯效果如下:

上傳

上傳前準(zhǔn)備工作以就緒,接下來就是點(diǎn)擊上傳,注意我這里因?yàn)橛衅渌畔?,需要一起上傳?/p>

如果只是單獨(dú)的上傳圖片一個(gè)功能,antdesign 提供的有現(xiàn)成的代碼,只需要在action屬性寫上后端地址即可。

點(diǎn)擊上傳

我們使用 antdesign 的表單提交功能,點(diǎn)擊上傳后得到一個(gè)values對(duì)象如下:

我們的圖片信息在pic字段下,這個(gè)字段是自己設(shè)置的,下面是點(diǎn)擊上傳文件相關(guān)代碼。

  const handleAddRequest = async (values: any) => {
    const formData = new FormData()
    if (values.pic && values.pic.fileList.length) {
      const file = values.pic.fileList[0].originFileObj
      formData.append('file', file, values.pic.fileList[0].name)
    }
 
    fetch(baseUrl + '/add-article', {
      method: 'POST',
      body: formData,
    })
      .then((res) => res.json())
      .then((res) => {
      })
      .catch((error) => {
      })
  }

首先創(chuàng)建一個(gè)新的 FormData 對(duì)象,用于構(gòu)建表單數(shù)據(jù)。

const formData = new FormData()

檢查是否存在圖片信息(values.pic),并且圖片文件列表(values.pic.fileList)不為空。

values.pic.fileList[0].originFileObj 則是獲取這個(gè)文件對(duì)象的原始文件對(duì)象。 

將文件添加到 FormData。

   const file = values.pic.fileList[0].originFileObj
   formData.append('file', file, values.pic.fileList[0].name)

注意 'file' 需要和后端讀取文件的命名一致,等會(huì)后端會(huì)介紹。

最后只需要將整理好的formData對(duì)象放到body中發(fā)給后端即可!

后端

首先安裝相關(guān)模塊

npm i express //用于接口請(qǐng)求
npm i multer  //文件模塊
npm i uuid    //文件命名

指定靜態(tài)頁面(圖片存儲(chǔ)文件夾)

app.use('/uploads/', express.static('./uploads')) //指定靜態(tài)頁面

解析Body數(shù)據(jù)

const bodyParser = require('body-parser')
app.use(bodyParser.json())

配置 multer 磁盤存儲(chǔ)

const storage = multer.diskStorage({
  destination: function (req, file, cb) {
    cb(null, 'uploads/')//圖片要存儲(chǔ)的文件夾地址
  },
  filename: function (req, file, cb) {
    cb(null, uuid.v1() + '.' + file.originalname.split('.').pop())//存儲(chǔ)的文件名
  },
})

使用配置好的存儲(chǔ)創(chuàng)建multer實(shí)例

const upload = multer({ storage: storage })

定義一個(gè)用于添加文章的路由,支持文件上傳

使用 upload.single('file') 作為中間件來處理帶有字段名 'file' 的單個(gè)文件上傳,這與上面前端上傳的命名相對(duì)應(yīng)( formData.append('file', file, values.pic.fileList[0].name))

app.post('/add-article', upload.single('file'), async (req, res) => {
  const filePath = 'uploads/' + req.file.filename // 獲取上傳文件存儲(chǔ)的文件路徑
  //todo....
})

最后上傳的圖片會(huì)存到uploads文件夾中

完整代碼

由于整個(gè)項(xiàng)目不單單是這一個(gè)功能,這里就把上傳圖片功能所用到的前后端代碼進(jìn)行分享,有需要的同學(xué)可以參考一下代碼!

前端

HTML      
 <Upload
              accept="multipart/form-data"
              name="avater"
              listType="picture-card"
              fileList={[]} // 手動(dòng)設(shè)置空的 fileList
              className="avatar-uploader"
              showUploadList={false}
              beforeUpload={(file) => {
                handlePreview(file)
                return false // 阻止默認(rèn)上傳行為
              }}
            >
              {imageUrl ? <img src={imageUrl} alt="avater" style={{ width: '100%' }} /> : uploadButton}
            </Upload>
 
JS
##上傳前操作
  const handlePreview = async (file: File) => {
    setImageUrl('')
    setLoading(true)
    const isImage = file.type.startsWith('image/')
    const isImageExtension = /\.(jpg|jpeg|png|gif)$/i.test(file.name)
 
    if (!isImage || !isImageExtension) {
      message.error(`${file.name} is not a supported image file`)
      return Upload.LIST_IGNORE
    }
 
    try {
      const reader = new FileReader()
      reader.onload = () => {
        setImageUrl(reader.result as string)
        setLoading(false)
      }
      reader.readAsDataURL(file)
    } catch (error) {
      console.error('圖片預(yù)覽失敗', error)
      message.error('圖片預(yù)覽失敗')
      setLoading(false)
    }
  }
 
##上傳處理字段
  const handleAddRequest = async (values: any) => {
    const formData = new FormData()
    if (values.pic && values.pic.fileList.length) {
      const file = values.pic.fileList[0].originFileObj
      formData.append('file', file, values.pic.fileList[0].name)
    }
 
    fetch(baseUrl + '/add-article', {
      method: 'POST',
      body: formData,
    })
      .then((res) => res.json())
      .then((res) => {
      })
      .catch((error) => {
      })
  }

后端

const express = require('express')
const multer = require('multer') //文件上傳模塊
const uuid = require('uuid') //生成隨機(jī)uuid-圖片命名需要
app.use('/uploads/', express.static('./uploads')) //指定靜態(tài)頁面
//解析Body數(shù)據(jù)
const bodyParser = require('body-parser')
app.use(bodyParser.json())
 
 
const storage = multer.diskStorage({
  destination: function (req, file, cb) {
    cb(null, 'uploads/')
  },
  filename: function (req, file, cb) {
    cb(null, uuid.v1() + '.' + file.originalname.split('.').pop())
  },
})
 
const upload = multer({ storage: storage })
 
// 新增文章
app.post('/add-article', upload.single('file'), async (req, res) => {
  const filePath = 'uploads/' + req.file.filename//存儲(chǔ)的文件名
  todo.....
})

以上就是React + Node.js實(shí)現(xiàn)圖片上傳功能的詳細(xì)內(nèi)容,更多關(guān)于React+Node.js圖片上傳的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • 詳解React中錯(cuò)誤邊界的原理實(shí)現(xiàn)與應(yīng)用

    詳解React中錯(cuò)誤邊界的原理實(shí)現(xiàn)與應(yīng)用

    在React中,錯(cuò)誤邊界是一種特殊的組件,用于捕獲其子組件樹中發(fā)生的JavaScript錯(cuò)誤,并防止這些錯(cuò)誤冒泡至更高層,導(dǎo)致整個(gè)應(yīng)用崩潰,下面我們就來看看它的具體應(yīng)用吧
    2024-03-03
  • React Native 中實(shí)現(xiàn)確認(rèn)碼組件示例詳解

    React Native 中實(shí)現(xiàn)確認(rèn)碼組件示例詳解

    這篇文章主要為大家介紹了React Native中實(shí)現(xiàn)確認(rèn)碼組件示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-08-08
  • React組件通信實(shí)現(xiàn)流程詳解

    React組件通信實(shí)現(xiàn)流程詳解

    這篇文章主要介紹了React組件通信,在開發(fā)中組件通信是React中的一個(gè)重要的知識(shí)點(diǎn),本文通過實(shí)例代碼給大家講解react中常用的父子、跨組件通信的方法,需要的朋友可以參考下
    2022-12-12
  • 使用React組件編寫溫度顯示器

    使用React組件編寫溫度顯示器

    這篇文章主要為大家詳細(xì)介紹了使用React組件編寫溫度顯示器,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-08-08
  • ReactNative集成個(gè)推消息推送過程詳解

    ReactNative集成個(gè)推消息推送過程詳解

    這篇文章主要為大家介紹了ReactNative集成個(gè)推消息推送過程詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-08-08
  • React高階組件優(yōu)化文件結(jié)構(gòu)流程詳解

    React高階組件優(yōu)化文件結(jié)構(gòu)流程詳解

    高階組件就是接受一個(gè)組件作為參數(shù)并返回一個(gè)新組件(功能增強(qiáng)的組件)的函數(shù)。這里需要注意高階組件是一個(gè)函數(shù),并不是組件,這一點(diǎn)一定要注意,本文給大家分享React 高階組件HOC使用小結(jié),一起看看吧
    2023-01-01
  • 十分鐘帶你快速了解React16新特性

    十分鐘帶你快速了解React16新特性

    這篇文章主要介紹了十分鐘帶你快速了解React16新特性,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2017-11-11
  • React?記憶緩存的三種方法實(shí)現(xiàn)

    React?記憶緩存的三種方法實(shí)現(xiàn)

    本文主要介紹了React?記憶緩存的三種方法實(shí)現(xiàn),包含React.memo、useMemo、useCallback,用于避免不必要的組件重渲染和計(jì)算,感興趣的可以了解一下
    2025-09-09
  • 利用CDN加速react webpack打包后的文件詳解

    利用CDN加速react webpack打包后的文件詳解

    下面小編就為大家分享一篇利用CDN加速react webpack打包后的文件詳解,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2018-02-02
  • 如何在react項(xiàng)目中做公共配置文件

    如何在react項(xiàng)目中做公共配置文件

    這篇文章主要介紹了如何在react項(xiàng)目中做公共配置文件問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-10-10

最新評(píng)論

乐山市| 齐齐哈尔市| 饶平县| 嘉义县| 西乌珠穆沁旗| 尼勒克县| 康乐县| 佳木斯市| 砀山县| 中方县| 黄山市| 珠海市| 洪洞县| 景洪市| 吴川市| 宁武县| 石渠县| 穆棱市| 南木林县| 和硕县| 自贡市| 西安市| 宁武县| 邹城市| 同江市| 敦煌市| 抚松县| 荔浦县| 深圳市| 丹江口市| 宁德市| 双江| 屏边| 泰州市| 濮阳市| 湘阴县| 大足县| 惠东县| 涡阳县| 汕尾市| 平阳县|