欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

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

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

效果

技術(shù)棧

前端:react+antdesign(upload組件)

后端:node+express+multer+uuid

前端

上傳前

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

       <Upload
              accept="multipart/form-data"
              name="avater"
              listType="picture-card"
              fileList={[]} // 手動設(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 表單中上傳文件時使用的編碼類型。它告訴服務(wù)器將表單數(shù)據(jù)編碼為 multipart/form-data 格式,這是用于上傳文件的一種常見方式。

beforeUpload:則是需要在上傳前對文件進(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)建一個新的FileReader對象。

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

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

在讀取完成時,觸發(fā) onload 事件。在這個函數(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)備工作以就緒,接下來就是點擊上傳,注意我這里因為有其他信息,需要一起上傳。

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

點擊上傳

我們使用 antdesign 的表單提交功能,點擊上傳后得到一個values對象如下:

我們的圖片信息在pic字段下,這個字段是自己設(shè)置的,下面是點擊上傳文件相關(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)建一個新的 FormData 對象,用于構(gòu)建表單數(shù)據(jù)。

const formData = new FormData()

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

values.pic.fileList[0].originFileObj 則是獲取這個文件對象的原始文件對象。 

將文件添加到 FormData。

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

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

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

后端

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

npm i express //用于接口請求
npm i multer  //文件模塊
npm i uuid    //文件命名

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

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

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

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

配置 multer 磁盤存儲

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())//存儲的文件名
  },
})

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

const upload = multer({ storage: storage })

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

使用 upload.single('file') 作為中間件來處理帶有字段名 'file' 的單個文件上傳,這與上面前端上傳的命名相對應(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 // 獲取上傳文件存儲的文件路徑
  //todo....
})

最后上傳的圖片會存到uploads文件夾中

完整代碼

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

前端

HTML      
 <Upload
              accept="multipart/form-data"
              name="avater"
              listType="picture-card"
              fileList={[]} // 手動設(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') //生成隨機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//存儲的文件名
  todo.....
})

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

相關(guān)文章

  • React中組件優(yōu)化的最佳方案分享

    React中組件優(yōu)化的最佳方案分享

    React組件性能優(yōu)化可以減少渲染真實DOM的頻率,以及減少VD比對的頻率,本文為大家整理了一些有效的React組件優(yōu)化方法,需要的小伙伴可以參考下
    2023-12-12
  • react項目升級報錯,babel報錯,.babelrc配置兼容等問題及解決

    react項目升級報錯,babel報錯,.babelrc配置兼容等問題及解決

    這篇文章主要介紹了react項目升級報錯,babel報錯,.babelrc配置兼容等問題及解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-08-08
  • React?路由使用示例詳解

    React?路由使用示例詳解

    這篇文章主要介紹了React?路由使用,使用路由時需要為組件指定一個路由的path,最終會以path為基礎(chǔ),進(jìn)行頁面的跳轉(zhuǎn),具體使用先看個簡單示例,該示例比較簡單就是兩個Tab頁面的來回切換
    2022-05-05
  • react在安卓中輸入框被手機鍵盤遮擋問題的解決方法

    react在安卓中輸入框被手機鍵盤遮擋問題的解決方法

    這篇文章主要給大家介紹了關(guān)于react在安卓中輸入框被手機鍵盤遮擋問題的解決方法,文中通過圖文以及示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面來一起看看吧
    2018-09-09
  • React項目開發(fā)中函數(shù)組件與函數(shù)式編程關(guān)系

    React項目開發(fā)中函數(shù)組件與函數(shù)式編程關(guān)系

    函數(shù)組件和函數(shù)式編程究竟是什么關(guān)系呢?本文會圍繞這個話題展開講解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-11-11
  • React報錯之組件不能作為JSX組件使用的解決方法

    React報錯之組件不能作為JSX組件使用的解決方法

    本文主要介紹了React報錯之組件不能作為JSX組件使用的解決方法,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2022-07-07
  • React實現(xiàn)基于Antd密碼強度校驗組件示例詳解

    React實現(xiàn)基于Antd密碼強度校驗組件示例詳解

    這篇文章主要為大家介紹了React實現(xiàn)基于Antd密碼強度校驗組件示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-01-01
  • 基于React+Redux的SSR實現(xiàn)方法

    基于React+Redux的SSR實現(xiàn)方法

    這篇文章主要介紹了基于React+Redux的SSR實現(xiàn)方法,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-07-07
  • React之錯誤邊界 Error Boundaries示例詳解

    React之錯誤邊界 Error Boundaries示例詳解

    這篇文章主要為大家介紹了React之錯誤邊界Error Boundaries示例教程,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-10-10
  • React配置Redux并結(jié)合本地存儲設(shè)置token方式

    React配置Redux并結(jié)合本地存儲設(shè)置token方式

    這篇文章主要介紹了React配置Redux并結(jié)合本地存儲設(shè)置token方式,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-01-01

最新評論