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

Node.js+Express.js+TS實(shí)現(xiàn)簡單圖床腳本

 更新時(shí)間:2023年10月16日 10:09:53   作者:泯瀧  
在這篇博客文章中,我將介紹如何使用 TypeScript 和 Express 框架來編寫一個(gè)簡單的圖床腳本,可以將本地圖片上傳到服務(wù)器,并返回圖片的 URL,這樣,你就可以在 Markdown 文檔中方便地引用圖片,而不用擔(dān)心圖片的存儲(chǔ)和管理問題

代碼實(shí)現(xiàn)

我將最新源碼放在了MoMeak9/img-service: 簡單圖床腳本,但是這個(gè)是最終版本,添加了很多新的在后續(xù)文章才提到的功能,而本文的完整代碼我放在了文末,請客官自行取用。

首先,我們需要安裝一些依賴包,包括 express、multer 和 dotenv。express 是一個(gè)流行的 Node.js Web 框架,提供了基本的路由和中間件功能。multer 是一個(gè)用于處理 multipart/form-data 類型的請求體的中間件,可以方便地獲取上傳的文件。fs 是 Node.js 的內(nèi)置模塊,用于操作文件系統(tǒng)。path 也是 Node.js 的內(nèi)置模塊,用于處理文件路徑。dotenv 是一個(gè)用于加載環(huán)境變量的模塊,可以讓我們將一些敏感或配置信息存放在 .env 文件中,而不用暴露在代碼里。

我們可以使用 npm 或 yarn 來安裝這些依賴包:

npm install express multer fs path dotenv
# or
yarn add express multer fs path dotenv

然后,我們需要在項(xiàng)目根目錄下創(chuàng)建一個(gè) .env 文件,用來存放一些配置信息,比如服務(wù)器端口號、圖片存儲(chǔ)路徑和訪問域名等。例如:

PORT=8899
BASEURL=https://fs.lwmc.net

接下來,我們需要在項(xiàng)目根目錄下創(chuàng)建一個(gè) src 文件夾,用來存放 TypeScript 源碼文件。在 src 文件夾下,我們創(chuàng)建一個(gè) index.ts 文件,作為入口文件。在 index.ts 文件中,我們首先需要導(dǎo)入一些模塊:

import express, {NextFunction, Request, Response} from 'express';
import multer from 'multer';
import fs from 'fs';
import path from 'path';
import dotenv from 'dotenv';

你也看出來了,我們還需要添加一些類型輔助

npm install @types/express @types/multer @types/node -D
# or
yarn add @types/express @types/multer @types/node -D

跨域配置(上傳和靜態(tài)文件跨域訪問能力)

// 允許跨域請求
app.use((req: Request, res: Response, next) => {
    res.header('Access-Control-Allow-Origin', '*');
    res.header('Access-Control-Allow-Methods', 'GET, POST');
    res.header('Access-Control-Allow-Headers', 'Content-Type, Authorization, Content-Length, X-Requested-With');
    next();
});

路由

應(yīng)該包含有靜態(tài)資源路由和上傳路由:

靜態(tài)資源路由開放對/uploads路徑下資源的訪問

// 靜態(tài)文件路由
app.use('/uploads', express.static(path.resolve(__dirname, '../uploads')));

上傳路由開放對/uploadPOST方法的訪問:

  • upload.single('file') 是一個(gè) multer 中間件,表示只允許上傳一個(gè)文件,并且上傳的文件參數(shù)名是 'file'。
  • (req: Request, res: Response) => { ... } 是路由處理函數(shù),當(dāng)客戶端向 '/upload' 路徑發(fā)送 POST 請求時(shí),會(huì)執(zhí)行這個(gè)函數(shù)。
  • const file = req.file; 表示從請求中獲取上傳的文件。
  • if (!file) { ... } 表示如果沒有上傳文件,返回一個(gè) 400 錯(cuò)誤響應(yīng)。
  • res.send({ ... }) 表示向客戶端發(fā)送一個(gè) JSON 響應(yīng),包含上傳文件的信息,包括文件名、原始文件名、文件類型、文件大小和文件的訪問路徑。其中文件訪問路徑是通過拼接服務(wù)器地址和文件路徑得到的。
// 上傳文件路由
app.post('/upload', upload.single('file'), (req: Request, res: Response) => {
    const file = req.file;
    if (!file) {
        res.status(400).send('Please upload a file.');
        return;
    }
    
    // 返回文件信息
    res.send({
        filename: file.filename,
        originalname: file.originalname,
        mimetype: file.mimetype,
        size: file.size,
        path: `http://localhost:3000/${commonPath}/${file.filename}`,
    });
    // 復(fù)原公共路徑
    commonPath = 'uploads/'
});

multer 配置

代碼使用了 multer 中間件來處理上傳文件的請求。Multer 是一個(gè) node.js 中間件,用于處理文件上傳,支持多文件上傳,可以設(shè)置文件大小、文件類型和保存路徑等。

以下是對代碼配置項(xiàng)的解釋:

  • dest 屬性指定上傳文件的保存目錄,這里設(shè)置為 'uploads/' 目錄下。如果目錄不存在,則會(huì)自動(dòng)創(chuàng)建。
  • limits 屬性設(shè)置上傳文件的限制,這里限制文件大小為 10MB。
  • fileFilter 屬性指定上傳文件的類型,這里限制只能上傳 image/png、image/jpeg、image/gif、image/webp、image/svg+xml 這些類型的文件。如果文件類型不在指定的類型列表中,則會(huì)觸發(fā)錯(cuò)誤。
  • storage 屬性指定上傳文件的存儲(chǔ)方式,這里使用了 diskStorage 存儲(chǔ)方式。在存儲(chǔ)文件時(shí),會(huì)根據(jù)上傳時(shí)間按年月日來創(chuàng)建文件夾,并將文件存儲(chǔ)在對應(yīng)的文件夾下。
  • filename 方法指定上傳文件的命名規(guī)則,這里使用時(shí)間戳加原始文件名的方式來命名文件。
// 上傳文件的中間件
const upload = multer({
    dest: 'uploads/',
    limits: {
        fileSize: 1024 * 1024 * 10, // 限制文件大小為10M
    },
    fileFilter: (req, file, cb) => {
        // 限制文件類型
        const allowedTypes = ['image/png', 'image/jpeg', 'image/gif', 'image/webp', 'image/svg+xml'];
        if (!allowedTypes.includes(file.mimetype)) {
            cb(new Error('Invalid file type.'));
            return;
        }
        cb(null, true);
    },
    storage: multer.diskStorage({
        destination: (req, file, cb) => {
            if (!fs.existsSync('uploads/')) {
                fs.mkdirSync('uploads/');
            }
            // 獲取日期
            const date = new Date();
            const year = date.getFullYear();
            const month = date.getMonth() + 1;
            const day = date.getDate();
            commonPath = path.join(commonPath, year.toString());
            if (!fs.existsSync(path.join(commonPath))) {
                fs.mkdirSync(path.join(commonPath));
            }
            commonPath = path.join(commonPath, month.toString().padStart(2, '0'));
            if (!fs.existsSync(path.join(commonPath))) {
                fs.mkdirSync(path.join(commonPath));
            }
            // 拼接路徑
            cb(null, commonPath);
        },
        filename: (req, file, cb) => {
            cb(null, `${Date.now()}${file.originalname}`);
        },
    }),
});

完整代碼:

import express, {Request, Response} from 'express';
import multer from 'multer';
import fs from 'fs';
import path from 'path';
const app = express();
// 公共路徑
let commonPath = 'uploads/';
// 上傳文件的中間件
const upload = multer({
    dest: 'uploads/',
    limits: {
        fileSize: 1024 * 1024 * 10, // 限制文件大小為10M
    },
    fileFilter: (req, file, cb) => {
        // 限制文件類型
        const allowedTypes = ['image/png', 'image/jpeg', 'image/gif', 'image/webp', 'image/svg+xml'];
        if (!allowedTypes.includes(file.mimetype)) {
            cb(new Error('Invalid file type.'));
            return;
        }
        cb(null, true);
    },
    storage: multer.diskStorage({
        destination: (req, file, cb) => {
            if (!fs.existsSync('uploads/')) {
                fs.mkdirSync('uploads/');
            }
            // 獲取日期
            const date = new Date();
            const year = date.getFullYear();
            const month = date.getMonth() + 1;
            const day = date.getDate();
            commonPath = path.join(commonPath, year.toString());
            if (!fs.existsSync(path.join(commonPath))) {
                fs.mkdirSync(path.join(commonPath));
            }
            commonPath = path.join(commonPath, month.toString().padStart(2, '0'));
            if (!fs.existsSync(path.join(commonPath))) {
                fs.mkdirSync(path.join(commonPath));
            }
            // 拼接路徑
            cb(null, commonPath);
        },
        filename: (req, file, cb) => {
            cb(null, `${Date.now()}${file.originalname}`);
        },
    }),
});
// 允許跨域請求
app.use((req: Request, res: Response, next) => {
    res.header('Access-Control-Allow-Origin', '*');
    res.header('Access-Control-Allow-Methods', 'GET, POST');
    res.header('Access-Control-Allow-Headers', 'Content-Type, Authorization, Content-Length, X-Requested-With');
    next();
});
// 靜態(tài)文件路由
app.use('/uploads', express.static(path.resolve(__dirname, '../uploads')));
// 上傳文件路由
app.post('/upload', upload.single('file'), (req: Request, res: Response) => {
    const file = req.file;
    if (!file) {
        res.status(400).send('Please upload a file.');
        return;
    }
    // 返回文件信息
    res.send({
        filename: file.filename,
        originalname: file.originalname,
        mimetype: file.mimetype,
        size: file.size,
        path: `http://localhost:3000/${commonPath}/${file.filename}`,
    });
    commonPath = 'uploads/'
});
// 啟動(dòng)服務(wù)器
const port = process.env.PORT || 3000;
app.listen(port, () => {
    console.log(`server started at http://localhost:${port}`);
});

以上就是Node.js+Express.js+TS實(shí)現(xiàn)簡單圖床腳本的詳細(xì)內(nèi)容,更多關(guān)于Node.js Express.js TS圖床腳本的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Node.js實(shí)現(xiàn)mysql連接池使用事務(wù)自動(dòng)回收連接的方法示例

    Node.js實(shí)現(xiàn)mysql連接池使用事務(wù)自動(dòng)回收連接的方法示例

    這篇文章主要介紹了Node.js實(shí)現(xiàn)mysql連接池使用事務(wù)自動(dòng)回收連接的方法,結(jié)合實(shí)例形式分析了node.js操作mysql連接池實(shí)現(xiàn)基于事務(wù)的連接回收操作相關(guān)技巧,需要的朋友可以參考下
    2018-02-02
  • 解決Node.js包管理器安裝報(bào)錯(cuò)npm?ERR!?code?1的問題

    解決Node.js包管理器安裝報(bào)錯(cuò)npm?ERR!?code?1的問題

    在開發(fā)過程中,我們經(jīng)常需要使用各種Node.js包來擴(kuò)展我們的應(yīng)用程序功能,這些包通常通過npm(Node.js包管理器)進(jìn)行安裝和管理,有時(shí)候我們可能會(huì)遇到一些關(guān)于npm的錯(cuò)誤,本文將詳細(xì)介紹如何解決這個(gè)問題,并提供一個(gè)詳細(xì)的實(shí)例,需要的朋友可以參考下
    2024-03-03
  • Node.js文件操作詳解

    Node.js文件操作詳解

    這篇文章主要介紹了Node.js文件操作詳解,本文講解了處理文件路徑講的一些方法、fs模塊詳細(xì)的使用和介紹等內(nèi)容,需要的朋友可以參考下
    2014-08-08
  • nodejs接入阿里大魚短信驗(yàn)證碼的方法

    nodejs接入阿里大魚短信驗(yàn)證碼的方法

    本篇文章主要介紹了nodejs接入阿里大魚短信驗(yàn)證碼的方法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下。
    2017-07-07
  • 利用node實(shí)現(xiàn)數(shù)據(jù)庫數(shù)據(jù)導(dǎo)出到Excel

    利用node實(shí)現(xiàn)數(shù)據(jù)庫數(shù)據(jù)導(dǎo)出到Excel

    本文將詳細(xì)講解如何使用Node.js實(shí)現(xiàn)從MySQL數(shù)據(jù)庫獲取數(shù)據(jù),并生成包含多個(gè)工作表的 Excel 文件,每個(gè)工作表對應(yīng)數(shù)據(jù)庫中的一個(gè)表,有需要的可以了解下
    2024-11-11
  • node.js中的fs.fchown方法使用說明

    node.js中的fs.fchown方法使用說明

    這篇文章主要介紹了node.js中的fs.fchown方法使用說明,本文介紹了fs.fchown方法說明、語法、接收參數(shù)、使用實(shí)例和實(shí)現(xiàn)源碼,需要的朋友可以參考下
    2014-12-12
  • npm?does?not?support?Node.js問題的解決辦法

    npm?does?not?support?Node.js問題的解決辦法

    這篇文章主要給大家介紹了關(guān)于npm?does?not?support?Node.js問題的解決辦法,文中通過代碼以及圖文介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2023-10-10
  • node.js實(shí)現(xiàn)websocket的即時(shí)通訊詳解

    node.js實(shí)現(xiàn)websocket的即時(shí)通訊詳解

    這篇文章主要介紹了深入淺出講解websocket的即時(shí)通訊,服務(wù)器可以主動(dòng)向客戶端推送信息,客戶端也可以主動(dòng)向服務(wù)器發(fā)送信息,是真正的雙向平等對話,屬于服務(wù)器推送技術(shù)的一種,需要的朋友可以參考下
    2023-05-05
  • nodejs+websocket實(shí)時(shí)聊天系統(tǒng)改進(jìn)版

    nodejs+websocket實(shí)時(shí)聊天系統(tǒng)改進(jìn)版

    這篇文章主要介紹了nodejs+websocket實(shí)時(shí)聊天系統(tǒng)的改進(jìn)版,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-05-05
  • VsCode開發(fā)環(huán)境之Node.js離線部署的實(shí)現(xiàn)步驟

    VsCode開發(fā)環(huán)境之Node.js離線部署的實(shí)現(xiàn)步驟

    本文主要介紹了VsCode開發(fā)環(huán)境之Node.js離線部署的實(shí)現(xiàn)步驟,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2025-09-09

最新評論

台北市| 高清| 墨竹工卡县| 浦东新区| 托里县| 荔浦县| 南皮县| 阆中市| 阜康市| 墨玉县| 天气| 凉城县| 监利县| 博白县| 锦屏县| 石屏县| 藁城市| 南城县| 娄底市| 和静县| 澄江县| 唐山市| 阜新| 大姚县| 兴宁市| 乳山市| 芮城县| 南宫市| 华蓥市| 鄄城县| 门源| 桐梓县| 德安县| 迁安市| 察隅县| 乌海市| 广宁县| 鄱阳县| 河北区| 渭南市| 耒阳市|