[英]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.