TypeORM 上传和服务(下载)文件

swi*_*ser 3 file download node.js express typeorm

介绍

\n\n

在我的项目中,我尝试将文件存储在 MySQL 中。用户可以上传文件(html WEB-APP)。之后用户就有了上传文件的列表(html WEB-APP),用户可以通过Link下载文件。在后端,我使用一个node.js(TypeORM)项目:

\n\n
    \n
  • “打字稿”:“3.3.3333”
  • \n
  • "body-parser": "^1.19.0",
  • \n
  • “调试”:“^4.1.1”,
  • \n
  • "express": "^4.17.1",
  • \n
  • "express-fileupload": "^1.1.6",
  • \n
  • "mysql": "^2.14.1",
  • \n
  • "reflect-metadata": "^0.1.10",
  • \n
  • “类型”:“0.2.22”
  • \n
\n\n

问题

\n\n
    \n
  • \xe2\x9c\x85 在我的代码中,我可以成功上传文件。
  • \n
  • \xe2\x9d\x8c 如果我尝试下载该文件,我得到一个无法读取或已损坏的文件。
  • \n
\n\n

下载文件时我的代码有什么问题?

\n\n

在此输入图像描述

\n\n

我的代码

\n\n

实体类

\n\n

文件.ts

\n\n
\nimport {Entity, Column, PrimaryGeneratedColumn} from "typeorm"\n\n@Entity()\nexport class MYFile{\n\n    @PrimaryGeneratedColumn()\n    id: number \n\n\n    @Column()\n    name: string\n\n    @Column({\n        type: "longblob"\n    })\n    data: string\n\n    @Column()\n    mimeType:string\n}\n\n
Run Code Online (Sandbox Code Playgroud)\n\n

应用程序脚本

\n\n

索引.ts

\n\n
\nimport "reflect-metadata";\nimport {createConnection, getRepository, getConnection} from "typeorm";\nimport * as express from \'express\';\nimport * as bodyParser from  "body-parser";\nimport http = require("http");\nvar debug = require(\'debug\')(\'rkdemo:server\');\nimport * as fileUpload from "express-fileupload";\nconst fs = require(\'fs\');\nimport {User} from "./entity/User";\nimport {MYFile} from "./entity/file"\n\nconst app = express();\nvar port = normalizePort(process.env.PORT || \'3000\');\nvar server = http.createServer(app);\napp.set(\'port\', port);\napp.use(bodyParser.json({limit: \'50mb\'}));\napp.use(bodyParser.urlencoded({limit: \'50mb\', extended: false }));\napp.use(fileUpload({\n    limits: { fileSize: 50 * 1024 * 1024 },\n}));\n\n\n\ncreateConnection().then(async connection => {\n\n\n\n    app.get(\'/\', (req, res) => {\n        res.send(\'Hello world!\');\n    });\n\n\n\n    app.get("/upload", (req, res)=>{\n        res.send(`<form action="http://localhost:3000/upload" method="post" enctype="multipart/form-data">\n        <label>W\xc3\xa4hlen Sie die hochzuladenden Dateien von Ihrem Rechner aus:\n          <input name="datein" type="file" multiple> \n        </label>  \n        <button>hochladen</button>\n      </form>`)\n    })\n\n\n\n    app.post("/upload", async (req, res)=>{\n        let fileData = req.files.datein\n\n        console.log(fileData);\n\n\n        if (Array.isArray(fileData)){\n            console.log("TODO: Array")\n        }else{\n\n            var newFile = new MYFile()\n            newFile.name = fileData.name\n            newFile.data = fileData.data.toString(\'base64\')\n            newFile.mimeType = fileData.mimetype\n\n            try {\n                const repo = getConnection().getRepository(MYFile)\n                const result_File = await repo.save(newFile)\n                res.send("Upload complete")\n            } catch (error) {\n                console.log(error)\n                res.send("ERROR")\n            }\n        }\n    })\n\n\n\n    app.get("/file/:id", async (req, res)=>{\n        try {\n            const repo = getConnection().getRepository(MYFile)\n            const result_find = await repo.findOne(req.params.id)\n            console.log(result_find);\n            var fileData = Buffer.from(result_find.data, \'base64\');\n            res.writeHead(200, {\n            \'Content-Type\': result_find.mimeType,\n            \'Content-Disposition\': \'attachment; filename=\' + result_find.name,\n            \'Content-Length\': fileData.length\n            });\n            res.write(fileData);\n            res.end();\n        } catch (error) {\n            console.log(error)\n            res.send("ERROR")\n        }\n    })\n}).catch(error => console.log(error));\n\n\n\nserver.listen(port, function () {\n    console.log(\'Example app listening on port: \' + port);\n  });\nserver.on(\'error\', onError);\nserver.on(\'listening\', onListening);\n\n\nfunction normalizePort(val) {\n    var port = parseInt(val, 10);\n    if (isNaN(port)) {\n      return val;\n    }\n    if (port >= 0) {\n      return port;\n    }\n    return false;\n  }\n\n\n\nfunction onError(error) {\n    if (error.syscall !== \'listen\') {\n      throw error;\n    }\n\n    var bind = typeof port === \'string\'\n      ? \'Pipe \' + port\n      : \'Port \' + port;\n\n    switch (error.code) {\n      case \'EACCES\':\n        console.error(bind + \' requires elevated privileges\');\n        process.exit(1);\n        break;\n      case \'EADDRINUSE\':\n        console.error(bind + \' is already in use\');\n        process.exit(1);\n        break;\n      default:\n        throw error;\n    }\n  }\n\n\n  function onListening() {\n    var addr = server.address();\n    var bind = typeof addr === \'string\'\n      ? \'pipe \' + addr\n      : \'port \' + addr.port;\n    debug(\'Listening on \' + bind);\n  }\n\n
Run Code Online (Sandbox Code Playgroud)\n

swi*_*ser 5

我解决了我的问题。

实体类

文件.ts

data: string改为data: Buffer

应用程序脚本

索引.ts

变成

app.post("/upload", async (req, res) => {
    ...
    newFile.data = fileData.data
    ...
})

... 

app.get("/file/:id", async (req, res) => {
    ...
    let fileData = result_find.data
    ... 
})
Run Code Online (Sandbox Code Playgroud)