【问题标题】:How can i refactor this code to get the image file displayed on the browser?如何重构此代码以使图像文件显示在浏览器上?
【发布时间】:2020-11-18 10:39:48
【问题描述】:

我想从本地磁盘中选择一个图像文件,然后单击按钮将其上传到服务器。一旦上传到服务器,服务器应该以图像作为响应返回给浏览器。这是我为实现这一目标而编写的一段代码:

         let querystring = require('querystring');
         import fs from 'fs';
         import formidable from 'formidable';
      function start(res){
        console.log("Request handler 'start' was called");
        let body =`<!DOCTYPE html>
        <html lang="en">
        <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Upload</title>
        </head>
        <body>
        <form action="/upload" enctype="multipart/form-data" method="post">
       <input type="file" name="upload" multiple="multiple">
       <button type="submit" value="Upload file">submit</button>
       </form>
        </body>
       </html>`;
      res.writeHead(200, {"content-type": "text/html"});
      res.write(body);
      res.end();
          }
  function upload(res, req){
     console.log("Request handler 'upload' was called");
     let form = new formidable.IncomingForm();
     console.log("about to parse");
     form.parse(req, (err,fields,file)=>{
     console.log("parsing done!");
     fs.rename(file.upload.path,"/tmp/test.png", (err)=>{
     if(err){
        fs.unlink("/tmp/test.png");
        fs.rename(file.upload.path, "/tmp/test.png");
        } });
       res.writeHead(200, {"Content-Type": "text/html"});
       res.write("received image:<br/>");
       res.write("<img src='/show' />");
      res.end();
      });}
   function show(res) {
      console.log("Request handler 'show' was called.");
      response.writeHead(200, {"Content-Type": "image/png"});
      fs.createReadStream("/tmp/test.png").pipe(res);}
      export {start,upload,show};

运行代码时出现以下错误;

    PS C:\Users\paullaster-geek\OneDrive\Desktop\Projects\Dive node> node -r esm index.js
    Response ready
    Request for / recieved
    About to route a request for /    
    Request handler 'start' was called
    Request for /upload recieved
    About to route a request for /upload 
    Request handler 'upload' was called  
    about to parse
    parsing done!
    TypeError [ERR_INVALID_CALLBACK]: Callback must be a function. Received undefined
    at makeCallback (fs.js:161:11)
    at Proxy.unlink (fs.js:1151:14)
    at C:\Users\paullaster-geek\OneDrive\Desktop\Projects\Dive node\requestHandlers.js:40:16
    at FSReqCallback.oncomplete (fs.js:164:23) {
    code: 'ERR_INVALID_CALLBACK'
     }
    PS C:\Users\paullaster-geek\OneDrive\Desktop\Projects\Dive node> 

【问题讨论】:

    标签: javascript node-modules fs formidable


    【解决方案1】:

    在为一个类似的项目苦苦挣扎之后,我找到了一个可行的解决方案。 首先,使用一个名为 formidable 的插件,从 npm 安装它。

    1.准备好您的 fileUploader.js 并将其存储到您的服务器项目文件夹中。

        var http = require('http');
        var formidable = require('formidable');
        var fs = require('fs');
            
            module.exports = exports ={                                            
            init_fileUploader: function() {  
            
            http.createServer(function (req, res) {
              if (req.url === '/fileupload') {
                var form = new formidable.IncomingForm();
                
                // CHECK FOR UNSUPPORTED FILE TYPES
                form.onPart = function (part) {
                if(!part.filename || part.filename.match(/\.(jpg|jpeg|png)$/i)) {
                    this.handlePart(part);
                }
                else {console.log(part.filename + ' is not allowed');}
                };
                
                 // RUN FILE HANDLING
                form.parse(req, function (err, fields, files) {
                  var oldpath = files.filetoupload.path;
                  var newpath = 'C:\yourNewPathHere' + files.filetoupload.name;
                  fs.copyFile(oldpath, newpath, function (err) {
                    if (err) throw err;
                    res.write('Image has been saved at:\r'+newpath);
                    res.end();
                  });
             });
              } else {
                res.writeHead(200, {'Content-Type': 'text/html'});
                res.write('<form action="fileupload" method="post" enctype="multipart/form-data">');
                res.write('<input type="file" name="filetoupload"><br>');
                res.write('<input type="submit">');
                res.write('</form>');
                return res.end();
              }
            }).listen(8080);
            }//END INIT LISTENER
            };// END MODULE EXPORT
    

    2。在服务器的 main.js 中导入并初始化连接

    let fileUploader = require(".yourPathHere/fileUploader.js");
    
    try{
    var msg3 = fileUploader.init_fileUploader();
    } catch (error) {console.log("Fatal error fileUploader: ",error,"\r");}
    

    3.测试一切是否正常 - > 运行你的主服务器并转到 http://localhost:8080,你应该会看到一个简单的表单来将你的文件(jpg、png)上传到服务器(到你的新路径位置假如)。你的图片应该从本地电脑上传到服务器文件夹。

    4.向客户端请求图片(前端)

    在您的 HTML 中创建一个 &lt;div id="ImageHolder"&gt;&lt;/div&gt;,然后在您的脚本中创建一个函数来显示之前生成的此上传表单。

    function uploadImage(){
    
    var url_src = "http://localhost or IP here:8080";
    
        $("#ImageHolder").empty();
     
        $('<iframe>')  // Creates the element
        .attr('src',url_src) 
        .attr('height',500)
        .attr('width',500)
        .appendTo('#ImageHolder');
     
    }  
    
    

    5.现在是棘手的部分!为了使用已上传的图像更新 ImageHolder,您必须将其转换为 base64 URI。

    我更喜欢服务器端,所以 ImageHandler.js 应该是这样的:

    module.exports = exports ={  
    
     convertToUri: function(path) {
            var promise = new Promise(function(resolve, reject) {  
      
            let contents = fs.readFileSync(path, {encoding: 'base64'});
            contents = 'data:image/png;base64,' + contents;
            resolve(contents);     
            });
    
      return promise;   
    },// END getImageFromList
    }; 
    

    6.最后向 imageHandler.js 发出一个后端请求,将文件上传方法中已经生成的路径作为参数并重新加载你的 imageHolder。

     $("#ImageHolder").empty();
    
            $('<iframe>')  // Creates the element
             .attr('src',yourVariableHereContainingBASE64uri ) 
             .attr('height',500)
             .attr('width',500)
             .appendTo('#ImageHolder');
    
    

    【讨论】:

      猜你喜欢
      • 2020-08-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-08-15
      相关资源
      最近更新 更多