Hi i am just trying to learn node js and i am trying to upload a file to different location in my computer but i am facing some issues...Here is my code...
var http = require('http');
var fs = require('fs');
var formidable = require('formidable');
http.createServer(function(req,res){
if(req.url == '/upload'){
var form = new formidable.IncomingForm();
form.parse(req,function(err,fields,files){
var oldpath = files.filetoupload.path;
var newpath = 'E:/Node/ResumeUpload/' + files.filetoupload.name;
fs.rename(oldpath,newpath,function(err){
if(err) console.log(err);
res.write('File uploaded sucessfully to ' + newpath);
res.end();
})
});
}
else{
fs.readFile('FileUpload.html',function(err,data){
res.writeHead(200,{'Content-Type' : 'text/html'});
res.write(data);
res.end();
});
}
}).listen(9090);
But the problem is it is showing error as below
var oldpath = files.filetoupload.path;
TypeError: Cannot read property 'path' of undefined
at E:\Node\FileUploading.js:8:46
at IncomingForm.<anonymous> (E:\Node\node_modules\formidable\lib\incoming_form.js:107:9)
at emitNone (events.js:106:13)
at IncomingForm.emit (events.js:208:7)
at IncomingForm._maybeEnd (E:\Node\node_modules\formidable\lib\incoming_form.js:557:8)
at E:\Node\node_modules\formidable\lib\incoming_form.js:238:12
at WriteStream.<anonymous> (E:\Node\node_modules\formidable\lib\file.js:79:5)
at Object.onceWrapper (events.js:313:30)
at emitNone (events.js:111:20)
at WriteStream.emit (events.js:208:7)
Can anybody suggest what would be the reason for this issue...!!
Thank You.
You can use try module multer in nodejs, you can upload file, you can see:Multer
//install multer
$ npm install --save multer
Related
the terminal is showing >>>
node:_http_outgoing:862
throw new ERR_INVALID_ARG_TYPE(
^
TypeError [ERR_INVALID_ARG_TYPE]: The "chunk" argument must be of type string or an instance of Buffer or Uint8Array. Received undefined
at new NodeError (node:internal/errors:399:5)
at write_ (node:_http_outgoing:862:11)
at ServerResponse.write (node:_http_outgoing:827:15)
at ReadFileContext.callback (c:\Users\me\Documents\Web Devolopment Challenge\intro\sample-server.js:7:9)
at FSReqCallback.readFileAfterOpen [as oncomplete] (node:fs:324:13) {
code: 'ERR_INVALID_ARG_TYPE'
}
Node.js v18.14.1
this is my code
var http = require('http')
var fs = require('fs')
http.createServer(function (req, res) {
fs.readFile('demofile1.html', function(err, data) {
res.writeHead(200, {'Content-Type': 'text/html'});
res.write(data);
return res.end();
});
}).listen(7000);
and this is my html code
<html>
<h1>hello guys</h1>
<h2>heyy</h2>
</html>
I am the beginner for nodejs and facing the question about using formidable to upload file problems:
Console Output:
[Error: ENOENT: no such file or directory, rename '/var/folders/my/b9y9l2zx583b0sz5zsc63g680000gn/T/ce455bd0f3e8df772aa8aba00' -> 'C:/Users/donlam/desktop/nodejs-uploadtutorial/69.png'] {
errno: -2,
code: 'ENOENT',
syscall: 'rename',
path: '/var/folders/my/b9y9l2zx583b0sz5zsc63g680000gn/T/ce455bd0f3e8df772aa8aba00',
dest: 'C:/Users/donlam/desktop/nodejs-uploadtutorial/69.png'
}
I searched some pervious case here and I try to solve it by reopen the folder, delete the package.json... But it seems not work. But I find the source file path is /var/ rather than the path I have chosen to upload. Is the problem be there?
Thank you so much.
My code
var http = require('http');
var formidable = require('formidable');
var fs = require('fs');
http.createServer(function (req, res) {
if (req.url == '/fileupload') {
var form = new formidable.IncomingForm();
form.parse(req, function (err, fields, files) {
var oldpath = files.filetoupload.filepath;
//var oldpath = files.fileupload.path;
var newpath = 'C:/Users/donlam/desktop/nodejs-uploadtutorial/' + files.filetoupload.originalFilename;
fs.rename(oldpath, newpath, function (err) {
if (err) throw err;
res.write('File uploaded and moved!');
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);
The problem is resolved, the destination folder really does not exist. Since the folder location is in the share drive, the C:// is wrong.
I was following this article to setup a nodejs server on my local machine (which has 16 gb memory and about 170gb free disk-space) and uploaded a 20 gb file, for the first couple of times the file got uploaded successfully, but after a while i started getting EPIPE error:
error FetchError: request to http://localhost:3200/upload failed, reason: write EPIPE
at ClientRequest.<anonymous> (/Volumes/FreeAgent GoFlex Drive/Test/multer-project/node_modules/node-fetch/lib/index.js:1455:11)
at ClientRequest.emit (events.js:327:22)
at Socket.socketErrorListener (_http_client.js:467:9)
at Socket.emit (events.js:315:20)
at emitErrorNT (internal/streams/destroy.js:100:8)
at emitErrorCloseNT (internal/streams/destroy.js:68:3)
at processTicksAndRejections (internal/process/task_queues.js:84:21) {
type: 'system',
errno: 'EPIPE',
code: 'EPIPE'
}
When i checked, the file got uploaded partially and was about 28mb in size. I tried uploading the file from both Postman, browser and a nodejs script, but got the same EPIPE error message. I am not sure why is this happening, googling the error message didn't help. I am not sure how to overcome this. Following is my server and client code.
// server.js
const express = require("express"); // Express Web Server
const busboy = require("connect-busboy"); // Middleware to handle the file upload https://github.com/mscdex/connect-busboy
const path = require("path"); // Used for manipulation with path
const fs = require("fs-extra");
const app = express(); // Initialize the express web server
app.use(
busboy({
highWaterMark: 2 * 1024 * 1024 // Set 2MiB buffer
})
); // Insert the busboy middle-ware
const uploadPath = path.join(__dirname, "uploads/"); // Register the upload path
fs.ensureDir(uploadPath); // Make sure that he upload path exits
/**
* Create route /upload which handles the post request
*/
app.route("/upload").post((req, res, next) => {
req.pipe(req.busboy); // Pipe it trough busboy
req.busboy.on("file", (fieldname, file, filename) => {
console.log(`Upload of '${filename}' started`);
// Create a write stream of the new file
const fstream = fs.createWriteStream(path.join(uploadPath, filename));
// Pipe it trough
file.pipe(fstream);
// On finish of the upload
fstream.on("close", () => {
console.log(`Upload of '${filename}' finished`);
res.send("ok");
});
});
});
/**
* Serve the basic index.html with upload form
*/
app.route("/").get((req, res) => {
res.writeHead(200, { "Content-Type": "text/html" });
res.write(
'<form action="upload" 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();
});
const server = app.listen(3200, function() {
console.log(`Listening on port ${server.address().port}`);
});
and my client code is:
// client.js
const fs = require("fs");
const FormData = require("form-data");
const fetch = require("node-fetch");
var formdata = new FormData();
formdata.append(
"file",
fs.createReadStream("/Users/phantom007/My Documents/35gb.myfile")
);
var requestOptions = {
method: "POST",
body: formdata,
redirect: "follow"
};
fetch("http://localhost:3200/upload", requestOptions)
.then(response => response.text())
.then(result => console.log(result))
.catch(error => console.log("error", error));
Answering my own question.
After strugging for a long time i figured out that this error was coming because the number of bytes getting written on the same is larger than the number of bytes sent to the server, so in my client code, i changed
this
fs.createReadStream("/Users/phantom007/My Documents/35gb.myfile")
to this
fs.createReadStream("/Users/phantom007/My Documents/35gb.myfile", { highWaterMark: 2 * 1024 * 1024 })
I am using multiparty. It was working fine but suddenly it is throwing error.
Error
err: { Error: stream ended unexpectedly
at Form.<anonymous> (/user_code/node_modules/multiparty/index.js:754:24)
at emitNone (events.js:91:20)
at Form.emit (events.js:185:7)
at finishMaybe (_stream_writable.js:514:14)
at endWritable (_stream_writable.js:524:3)
at Form.Writable.end (_stream_writable.js:489:5)
at onend (_stream_readable.js:511:10)
at _combinedTickCallback (internal/process/next_tick.js:73:7)
at process._tickDomainCallback (internal/process/next_tick.js:128:9) status: 400, statusCode: 400 }
Code
const functions = require('firebase-functions');
const admin = require('firebase-admin');
admin.initializeApp(functions.config().firebase);
var multiparty = require('multiparty');
var http = require('http');
var util = require('util');
exports.helloWorld = functions.https.onRequest((request, response) => {
var body = "";
var POST = {};
var form = new multiparty.Form();
form.on('error', function(err) {
console.log('Error parsing form: ' + err.stack);
});
form.parse(request, function(err, fields, files) {
response.status(500).send({
message: err
});
})
});
});
The "stream ended unexpectedly" error implies the underlying TCP socket was closed before a complete multipart form was received.
As you say this was previously working you should check the server to which you are making the request for any errors which may be closing the response early. One common cause is the size of the response data being larger than accepted by the server or request/response headers.
I am new in NodeJS, and I am working an an example:
function test(req,res){
var path = urls[Math.floor(Math.random()*urls.length)];
console.log("try to redirect to:"+path);
http.get(path,function(res_server){
//how to send the data from res_server to res
});
}
And the urls is an array of url.
I wonder how can I send the data from the res_server to the original client response?
BTW, the url maybe http or https.
update
var urls=["url1","url2","url3"];
var path = urls[Math.floor(Math.random()*urls.length)]; // find an random item from the array
update:2
Fine, this is the complete simple test script:
var http=require("http");
http.createServer(function(req, res1) {
var url = 'http://www.google.com.hk/images/srpr/logo11w.png';
var hp=require("http");
hp.get(url, function(res2) {
res2.pipe(res1);
});
}).listen(3000);
It works, but if you change http://www.google.com.hk/...logo..png to https:/www.google.....png
It will throw error:
http.js:1840
throw new Error('Protocol:' + options.protocol + ' not supported.');
^
Error: Protocol:https: not supported.
at Object.exports.request (http.js:1840:11)
at Object.exports.get (http.js:1847:21)
at Server.<anonymous> (C:\Users\maven\Desktop\t.js:6:6)
at Server.EventEmitter.emit (events.js:98:17)
at HTTPParser.parser.onIncoming (http.js:2108:12)
at HTTPParser.parserOnHeadersComplete [as onHeadersComplete] (http.js:121:23)
at Socket.socket.ondata (http.js:1966:22)
at TCP.onread (net.js:525:27)
Change var http = require('http'); to var http = require('https');
I do not fully understand your example. Looks strange to me. However best would be to pipe the request response into the server response:
http.createServer(function(req, res1) {
var path = url.format({
protocol: 'http:',
host: 'www.google.com'
});
http.get(path, function(res2) {
res2.pipe(res1);
});
}).listen(3000);