使用带有 typescript

问题描述

我用multer成功上传图片,保存在本地目录,保存路径到数据库。但是由于 heroku 没有将图像保存在本地目录中,所以我必须将图像上传到 Cloudinary,但 Cloudinary 需要将文件转换为 base64。

这是 node.js 中的实现:

const path = require("path");
const DataUri = require("datauri");

const dUri = new DataUri();

exports.dataUri = (file: Express.Multer.File): string =>
  dUri.format(path.extname(file.originalname).toString(),file.buffer);

我试图在这样的打字稿中实现它:

import path from "path";
import DataUri from "datauri";
// here is cauinsg issue
const dUri = new DataUri();

export const dataUri = (file: Express.Multer.File): string =>
  dUri.format(path.extname(file.originalname).toString(),file.buffer);


在打字稿实现中,我收到了 const dUri = new DataUri() 的打字稿错误

(alias) function DataUri(fileName: string,handler?: DataURI.Callback | undefined): Promise<string | undefined>

Expected 1-2 arguments,but got 0.ts(2554)
index.d.ts(2,31): An argument for 'fileName' was not provided.
'new' expression,whose target lacks a construct signature,implicitly has an 'any' type.

我不明白为什么 new DataUri() 在 olain 节点中有效,但在打字稿中无效。我认为这会是 ts 文件错误,所以忽略了它,但它没有用。当我启动应用程序时,我收到此错误:“UnhandledPromiseRejectionWarning:TypeError [ERR_INVALID_ARG_TYPE]:“路径”参数必须是字符串类型或缓冲区或 URL 的实例。接收未定义”

我没有创建函数,而是尝试在控制器中这样实现:

 const image = req.file;
  const file64=new DataUri(image.buffer)

这也不起作用

解决方法

老实说,我只使用过几次打字稿,但对于替代解决方案,您可以使用它。 在我使用 multer 使用纯 node.js 完成 base64 图像上传之前,它运行良好。我只留下实际的部分,所以你可以根据你的需要使用(只需在那里编辑你想要的):

routes/product.js

const productController = require('./controllers/product');
const { Router } = require('express');
const router = Router();
const multerUpload = require('./utilities/multer');

router.post('/form-data-upload',multerUpload.single('image'),productController.uploadFormDataImage);
router.post('/base64-upload',productController.uploadBase64Image);

module.exports = router;

controllers/product.js

const fs = require('fs');
const path = require('path');
const port = process.env.APP_PORT;
const appUrl = process.env.APP_URL;

module.exports = {
    uploadFormDataImage: (req,res,next) => {
        return res.status(201).json({
            error: false,message: "Image was successfully uploaded.",url: `${appUrl}:${port}/images/${req.file.filename}`
        });
    },uploadBase64Image: async (req,next) => {
        try {
            const encoded = req.body.image;
            const base64ToArray = encoded.split(";base64,");
            const prefix = base64ToArray[0];
            const extension = prefix.replace(/^data:image\//,'');

            if (extension === 'jpeg' || extension === 'jpg' || extension === 'png')
            {
                const imageData = base64ToArray[1];
                const fileName = (new Date().getTime() / 1000|0) + '.' + extension;
                const imagePath = path.join(__dirname,'./uploads/') + fileName;
                fs.writeFileSync(imagePath,imageData,{ encoding: 'base64' });

                return res.status(201).json({
                    error: false,message: "Base64 Image was successfully uploaded.",url: `${appUrl}:${port}/images/${fileName}`
                });
            }
            else {
                return res.status(403).json({
                    error: true,message: "Base64 data not valid!",});
            }
        }
        catch (e) {
            return res.status(403).json({
                error: true,message: e.message,});
        }
    },};

utilities/multer.js

const multer = require('multer');
const path = require('path');

module.exports = multer({
    storage: multer.diskStorage({
        destination: function (req,file,cb) {
            const filePath = path.join(__dirname,'./uploads');
            cb(null,filePath);
        },filename: function (req,cb) {
            const extension = file.mimetype.split('/')[1];
            const fileName = (new Date().getTime() / 1000 | 0) + '.' + extension;
            cb(null,fileName);
        }
    }),limits: {
        fileSize: 1024 * 1024 * 10 // MB
    },fileFilter: (req,cb) => {
        let valid = (file.mimetype === 'image/jpeg' || file.mimetype === 'image/jpg' || file.mimetype === 'image/png');
        cb(null,valid);
    },});
,

在构建 JS 中有一个程序来读取 base64 中的文件。有关 FileReader

的更多详细信息
const fr = new FileReader();
fr.onload = (data) => {
            console.log(data.target.result);
            // the result here will contain the base64 string.
        }

fr.readAsDataURL(file);
,

这是我的解决方案:

import DatauriParser from "datauri/parser";
const parser = new DatauriParser();

由于我使用 multer 并将图像存储到内存中,因此我得到 req.filereq.file.buffer

 const extName = path.extname(req.file.originalname).toString();
  const file64 = parser.format(extName,req.file.buffer);

然后

        const result = await Cloudinary.upload(file64.content!);