Javascript 如何防止在编辑表单时删除上载的图像?

Javascript 如何防止在编辑表单时删除上载的图像?,javascript,node.js,forms,rest,image-uploading,Javascript,Node.js,Forms,Rest,Image Uploading,我正在开发一个允许用户发布事件的应用程序。我正在使用NodeJS、Express和Mongo 我创建了一个表单,允许用户输入事件详细信息,并上传与事件相关的图像。我还创建了一个表单,允许用户编辑事件详细信息 表格如下: 问题: 用户用事件详细信息填写表单并附加图片 用户提交表单 用户决定更改事件标题,但不更改其他内容 用户单击编辑事件、更改标题并提交 问题:即使用户没有删除与事件相关的图片,图片也不再存在。 这里是我的new.ejs文件的一部分(用于发布新事件,只需将其添加到此处以供参考) 基

我正在开发一个允许用户发布事件的应用程序。我正在使用NodeJS、Express和Mongo

我创建了一个表单,允许用户输入事件详细信息,并上传与事件相关的图像。我还创建了一个表单,允许用户编辑事件详细信息

表格如下:

问题:

  • 用户用事件详细信息填写表单并附加图片
  • 用户提交表单
  • 用户决定更改事件标题,但不更改其他内容
  • 用户单击编辑事件、更改标题并提交
  • 问题:即使用户没有删除与事件相关的图片,图片也不再存在。
  • 这里是我的new.ejs文件的一部分(用于发布新事件,只需将其添加到此处以供参考)

    基本上,如果我在编辑表单中保持图像不变,req.file不存在。因此,req.body.image=未定义。并且图像不再与事件关联

    常识会这么说

        if(req.file) {
            filepath = req.file.path.substr(7); 
            req.body.image = filepath;
        }
    
    但是如果这样做,就会带来一个新的问题:如果用户编辑事件并删除图像(即决定他不想要与事件关联的图像),则图像永远不会被删除


    知道如何解决这个问题吗?我知道我必须在edit.ejs脚本中做些什么。。。更具体地说,我需要创建一个图像文件。。。但是我不知道如何处理这个问题,所以我通过一个我真的不喜欢的黑客程序来解决这个问题。我确信有一种更好、更干净、标准的方法来处理edit.ejs和图像。换句话说,请帮我找到更好的解决方案

    下面是edit.ejs中的更改

    <form action="/events/<%=event._id%>?_method=PUT" 
          method="POST"
          enctype="multipart/form-data" 
          onSubmit="return validate(this) & editPageImageProcessing(this);"
          novalidate >
         ....
         ....
           <div id="preview">
              <script>
                      var imageExists = '<%=event.image%>';
                      if(imageExists) {
                             var myImg = document.createElement("IMG");
                             var source = "../../<%= event.image %>";
                             myImg.src = source; 
                             myImg.name = "previewImage";
                             myImg.id = "previewImage";
                             adjustImageSize(myImg);
                             $('#preview').append(myImg);
                       }
              </script>
          </div>
    
    并增加了一个函数editPageImageProcessing

    此函数的作用是:如果用户没有上传新图像,也没有删除图像,则创建一个隐藏的输入字段“hiddenImage”,并将其值作为原始图像的源。见下文:

    // This function deals with edit image
    function editPageImageProcessing(form) {
        // If the user didn't change the image
                 // preview would be NOT hidden
                 // there would not be a req.file (document.getElementById('image').val == '')
                 // we want a hiddenimage input field
        var aFile = document.getElementById('image').value;
        console.log("File: ", aFile);
        var preview = document.getElementById('preview');
        console.log("Preview has hidden class: " + $(preview).hasClass('hidden'));
        if(aFile == '' && !$(preview).hasClass('hidden')) {
            var input = document.createElement('input');
            $(input).attr("name", "hiddenImage");
            $(input).attr("id", "hiddenImage");
            $(input).attr("type", "hidden");
            var myImage = document.getElementById('previewImage');
            $(input).attr("value", myImage.src);
            $('form').append(input); 
        }
        return true;
    }
    
    现在,在编辑路线中,我这样做了

    // UPDATE SPECIFIC EVENT IN DATABASE 
    router.put("/:id", upload.single('image'), middleware.checkEventOwnership, function(req, res) {
        var filepath = undefined;
        if(req.file) { // If user uploaded a new image
            filepath = req.file.path.substr(7); // Substr to remove "/public"
            console.log(filepath);
        } else if(req.body.hiddenImage) { // If user kept the same image
            var index = req.body.hiddenImage.lastIndexOf("/uploads");
            filepath = req.body.hiddenImage.substr(index);
            // req.body.hiddenImage WILL ONLY EXIST if user left image unchanged
        }
    
        req.body.image = filepath; // If user deleted image, this will be undefined, which is what we want
    
        Event.findByIdAndUpdate(req.params.id, req.body, function(err, foundEvent) {
           if(err) {
               console.log(err);
               req.flash("error", err);
           } else {
               req.flash("success", "Successfully edited your event");
           }
           res.redirect("/events/" + req.params.id);
        });
    });
    
    好吧,所以很乱

    如果有更好的解决办法,我们将不胜感激

        if(req.file) {
            filepath = req.file.path.substr(7); 
            req.body.image = filepath;
        }
    
    <form action="/events/<%=event._id%>?_method=PUT" 
          method="POST"
          enctype="multipart/form-data" 
          onSubmit="return validate(this) & editPageImageProcessing(this);"
          novalidate >
         ....
         ....
           <div id="preview">
              <script>
                      var imageExists = '<%=event.image%>';
                      if(imageExists) {
                             var myImg = document.createElement("IMG");
                             var source = "../../<%= event.image %>";
                             myImg.src = source; 
                             myImg.name = "previewImage";
                             myImg.id = "previewImage";
                             adjustImageSize(myImg);
                             $('#preview').append(myImg);
                       }
              </script>
          </div>
    
                             myImg.name = "previewImage";
                             myImg.id = "previewImage";
    
    // This function deals with edit image
    function editPageImageProcessing(form) {
        // If the user didn't change the image
                 // preview would be NOT hidden
                 // there would not be a req.file (document.getElementById('image').val == '')
                 // we want a hiddenimage input field
        var aFile = document.getElementById('image').value;
        console.log("File: ", aFile);
        var preview = document.getElementById('preview');
        console.log("Preview has hidden class: " + $(preview).hasClass('hidden'));
        if(aFile == '' && !$(preview).hasClass('hidden')) {
            var input = document.createElement('input');
            $(input).attr("name", "hiddenImage");
            $(input).attr("id", "hiddenImage");
            $(input).attr("type", "hidden");
            var myImage = document.getElementById('previewImage');
            $(input).attr("value", myImage.src);
            $('form').append(input); 
        }
        return true;
    }
    
    // UPDATE SPECIFIC EVENT IN DATABASE 
    router.put("/:id", upload.single('image'), middleware.checkEventOwnership, function(req, res) {
        var filepath = undefined;
        if(req.file) { // If user uploaded a new image
            filepath = req.file.path.substr(7); // Substr to remove "/public"
            console.log(filepath);
        } else if(req.body.hiddenImage) { // If user kept the same image
            var index = req.body.hiddenImage.lastIndexOf("/uploads");
            filepath = req.body.hiddenImage.substr(index);
            // req.body.hiddenImage WILL ONLY EXIST if user left image unchanged
        }
    
        req.body.image = filepath; // If user deleted image, this will be undefined, which is what we want
    
        Event.findByIdAndUpdate(req.params.id, req.body, function(err, foundEvent) {
           if(err) {
               console.log(err);
               req.flash("error", err);
           } else {
               req.flash("success", "Successfully edited your event");
           }
           res.redirect("/events/" + req.params.id);
        });
    });