简体   繁体   English

我如何重构此代码以使图像文件显示在浏览器上?

[英]How can i refactor this code to get the image file displayed on the browser?

I want to choose an image file from my local disk and upload it to the server on a button click.我想从我的本地磁盘中选择一个图像文件,然后单击按钮将其上传到服务器。 once uploaded to the server, the server should respond back to the browser with the image as the response.上传到服务器后,服务器应将图像作为响应返回给浏览器。 This is the piece of code i have written to achieve that:这是我为实现这一目标而编写的一段代码:

         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};

I get the following error when i run the code;运行代码时出现以下错误;

    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> 

After struggling a lot for a similar project, I've found a solution that worked.在为一个类似的项目奋斗了很多之后,我找到了一个有效的解决方案。 First of all, make use of a plugin called formidable, install it from npm.首先,使用一个名为 formidable 的插件,从 npm 安装它。

1. Prepare your fileUploader.js and store it to your server project folder. 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. Import and initialize connection inside your server's main.js 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. TESTING IF EVERYTHING WORKS - > Run your main server and go to http://localhost:8080, you should see a simple form to upload your file (jpg, png) to the server (to the new path location you provided). 3. 测试是否一切正常 -> 运行你的主服务器和 go 到 http://localhost:8080,你应该会看到一个简单的表格来上传你的文件(jpg,png)到服务器(到你提供的新路径位置) . Your image should be uploaded from local pc to server folder.您的图片应该从本地电脑上传到服务器文件夹。

4. Request image from client (frond end) 4. 客户端请求图片(前端)

In your HTML create a <div id="ImageHolder"></div> then inside your script make a function to show this upload form generated previously.在您的 HTML 中创建一个<div id="ImageHolder"></div>然后在您的脚本中创建一个 function 以显示之前生成的上传表单。

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. Now the tricky part. 5. 现在是棘手的部分。 in order to update ImageHolder with the already uploaded image you have to convert it to base64 URI.为了使用已上传的图像更新 ImageHolder,您必须将其转换为 base64 URI。

i prefer server side, so an ImageHandler.js should look like this:我更喜欢服务器端,所以 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. Finally make a backend request to imageHandler.js giving as argument the already generated path from file upload method and reload your imageHolder. 6. 最后向 imageHandler.js 发出后端请求,将文件上传方法中已生成的路径作为参数,并重新加载您的 imageHolder。

 $("#ImageHolder").empty();

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM