node.js实现图片上传

本文详细介绍了如何使用Node.js和Multer插件实现图片上传至服务器,并将图片路径保存到数据库的方法。通过设置图片名唯一性,避免重复上传覆盖原有图片,同时探讨了数据库中存储图片路径的最佳实践。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

两步走战略:
  • 将图片上传到服务器
  • 将图片的路径保存到数据库
图片上传到服务器
  • 下载第三方插件multer
npm install multer --save
  • 先写一个上传图片的接口
    在路由文件夹中创建一个upload.js文件:
const express=require('express');
const router=express.Router();
//上传图片的模板
var multer=require('multer');
//生成的图片放入uploads文件夹下
var upload=multer({dest:'uploads/'})
//图片上传必须用post方法
router.post('/img',upload.single('test'),(req,res)=>{
    console.log(req.file);
    res.send('upload img')
})
module.exports=router;

在服务器端server.js文件中:

const express = require('express')
var bodyParser = require('body-parser')
const app = express()
const cors=require('cors')
app.use(cors())
app.use(bodyParser.urlencoded({ extended: false }))
app.use(bodyParser.json())
// 配置静态资源目录 整一个文件夹 通过域名能访问
app.use(express.static(path.join(__dirname,"../static")))
//数据模型
//路由配置
const upload=require('./router/upload.js');
app.use('/upload',upload)
app.listen(80, () => console.log("服务器开启"))

设置完之后图片上传的接口为:http://127.0.0.1/upload/img
(可通过postman测试一下)

在这里插入图片描述
一起来看一下打印的req.file里面有些什么
在这里插入图片描述
上传的图片是一堆二进制码,不能查看,怎么办呢?我们可以用原文件名(originalname)拼接一个可访问路径呀

router.post('/img',upload.single('test'),(req,res)=>{
//读取路径(req.file.path)
    fs.readFile(req.file.path,(err,data)=>{
    //读取失败,说明没有上传成功
        if(err){return res.send('上传失败')}  
     //否则读取成功,开始写入
     //我们先尝试用原文件名originalname写入吧
     // 三个参数
     //1.图片的绝对路径
     //2.写入的内容
     //3.回调函数  
      fs.writeFile(path.join(__dirname,'../../static/img/'+req.file.originalname),data,(err)=>{
            if(err){return res.send('写入失败')}
            res.send({err:0,msg:'上传ok'})
        })
    })
})
module.exports=router;

在这里插入图片描述
能成功看到图片了,而不再是二进制的形式。
但是呢,这样有个弊端,如果上传的文件名一样,后面上传的图片会把前面上传的图片覆盖。
所以我们应该保证图片名的唯一性,可以通过时间戳+随机数的方式来尽量保证唯一性

        //声明图片名字为时间戳和随机数拼接成的,尽量确保唯一性
        let time=Date.now()+parseInt(Math.random()*999)+parseInt(Math.random()*2222);
        //拓展名
        let extname=req.file.mimetype.split('/')[1]
        //拼接成图片名
        let keepname=time+'.'+extname      
        //绝对路径就可以写成以下形式
        path.join(__dirname,'../../static/img/'+keepname)

完整代码:

const express=require('express');
const router=express.Router();
const fs=require('fs');
const path=require('path');
//上传图片的模板
var multer=require('multer');
//生成的图片放入uploads文件夹下
var upload=multer({dest:'uploads/'})
//图片上传必须用post方法
router.post('/img',upload.single('test'),(req,res)=>{
    //读取文件路径
    fs.readFile(req.file.path,(err,data)=>{
        //如果读取失败
    if(err){return res.send('上传失败')}
    //如果读取成功
    //声明图片名字为时间戳和随机数拼接成的,尽量确保唯一性
    let time=Date.now()+parseInt(Math.random()*999)+parseInt(Math.random()*2222);
    //拓展名
    let extname=req.file.mimetype.split('/')[1]
    //拼接成图片名
    let keepname=time+'.'+extname
    //三个参数
    //1.图片的绝对路径
    //2.写入的内容
    //3.回调函数
    fs.writeFile(path.join(__dirname,'../../static/img/'+keepname),data,(err)=>{
        if(err){return res.send('写入失败')}
        res.send({err:0,msg:'上传ok'})
    });
 });
})
module.exports=router;

将图片上传服务器ok啦!!!

将图片的路径保存到数据库

我们来想一想应该把什么保存在数据库中,相对路径还是绝对路径??
首先肯定不能把绝对路径保存到数据库中,一个ip可以有多个域名,虽然ip换不了,但是域名能换,如果整体存进去下次域名不同就会导致不能访问了。
那我们就得用相对路径了,相对路径存哪部分呢?
比如我填一个表格需要上传图片,可以先不存入数据库,先调用一个上传图片的接口,把相对路径返回给前端,前端可通过拼接的方式获取图片,再把表格中的其他数据及这个图片的相对路径一起放入数据库中。
(上传成功之后再传一个相对路径给前端)

res.send({err:0,msg:'上传ok',data:'/img/'+keepname})

在这里插入图片描述
接口跑通啦!!!

前端部分
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
    <style>
        img{
            width: 50px;
            height: 50px;
        }
    </style>
    <script src="../js/jquery.js"></script>
</head>
<body>
    <input type="file" name='image' id="imagelist">
    <img src="">
    <button onclick="Req_ajax()"> 上传</button>
<script>
    var OL_Action_Root = "http://127.0.0.1";
function Req_ajax()
{           
    console.log(111)
    console.log($("#imagelist")[0].files)
    // 获取file域里的图片信息
     var formData = new FormData()
     //创建formdata对象
    formData.append("test",$("#imagelist")[0].files[0])  
    // 将文件信息 append 进入formdata对象  key值 为后台 single 设置的值  
    $.ajax({
        url: OL_Action_Root+'/upload/img',
        type: 'POST',
        data: formData,
        cache: false,
        contentType: false,
        processData: false,
        success: function(data){
           if (data.err==0) {
               $('img').attr('src',OL_Action_Root+data.data)
           }
        },
        error: function(jqXHR, textStatus, errorThrown){
            document.getElementById("status").innerHTML = "<span style='color:#EF0000'>连接不到服务器,请检查网络!</span>";
        }
    });
}

</script>
</body>
</html>

让我们一起来看一下最终实现效果:
在这里插入图片描述

评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值