nodejs router Internal server error in summernote - node.js

I'm using summernote for my text editor.
I was making image upload function by using multer.
This is my summernote function.
onImageUpload : function(files, editor, welEditable){
// 파일 업로드(다중업로드를 위해 반복문 사용)
for (var i = files.length - 1; i >= 0; i--) {
sendFile(files[i], editor, welEditable);
}
}
and this is sendFile function
function sendFile(file, editor, welEditable){
console.log(file)
data = new FormData();
data.append("file", file);
$.ajax({
data: data,
type: "POST",
url: "/post/img",
cache: false,
contentType: false,
processData: false,
success: function(url) {
console.log(url)
editor.insertImage(welEditable, url);
}
});
}
Console shows file data normally, but
url: "/post/img" doesn't work well
Just in case, my post/img router code is like
router.post("/img", upload.array("note-dialog-image-file-16755274670761", 4), (req, res) => {
console.log("파일 이름 : ", req.files);
let urlArr = new Array();
for (let i = 0; i < req.files.length; i++) {
urlArr.push(`/img/${req.files[i].filename}`);
console.log(urlArr[i]);
}
let jsonUrl = JSON.stringify(urlArr);
res.json(jsonUrl);
});

In the multer middleware definition change the field name
router.post("/img", upload.array("note_dialog_image_file"), (req, res) => {
console.log("파일 이름 : ", req.files);
let urlArr = new Array();
for (let i = 0; i < req.files.length; i++) {
urlArr.push(`/img/${req.files[i].filename}`);
console.log(urlArr[i]);
}
let jsonUrl = JSON.stringify(urlArr);
res.json(jsonUrl);
});
and in the UI the FormData has to be changed, so that the file is pointed with correct field name
data = new FormData();
data.append("note_dialog_image_file", file);

Related

How do I access files from FormData of an AJAX Post

I currently have the following AJAX POST request sending the FormData() of the loaded file.
It takes in however many files uploaded, places them into a new form, and then posts that form as data to the /api/file URL
$('#file').on('change', function(){
var files = $(this).get(0).files;
$('#file').ready(function(){
if (files.length > 0){
var formData = new FormData();
for (var i = 0; i < files.length; i++) {
var file = files[i];
console.log(file);
var tmppath = URL.createObjectURL(event.target.files[0]);
formData.append('userFile', tmppath);
}
$.ajax({
url: '/api/file',
type: 'POST',
data: formData,
processData: false,
contentType: false,
success: function(data){
console.log('upload successful!\n' + data);
document.getElementById('ipfs').href = 'https://ipfs.infura.io/ipfs/' + data;
document.getElementById('ipfs').innerHTML = data;
},
xhr: function() {
var xhr = new XMLHttpRequest();
xhr.upload.addEventListener('progress', function(evt) {
if (evt.lengthComputable) {
var percentComplete = evt.loaded / evt.total;
percentComplete = parseInt(percentComplete * 100);
$('.progress-bar').text(percentComplete + '%');
$('.progress-bar').width(percentComplete + '%');
if (percentComplete === 100) {
$('.progress-bar').html('Done');
}
}
}, false);
return xhr;
}
});
}
});
and the following express node app
app.post('/api/file', async function(req,res){
console.log(await req.files);
});
And all it prints out is Null.

Send .zip file from service to nodejs app and after that to browser

I'm trying to send a zip file from Server(A) to Server(B)
Browser
$.ajax({
url: 'routes/getFile',
method: "POST",
contentType: 'application/json',
success: function (data) {
var byteCharacters = data;
var byteNumbers = new Array(byteCharacters.length);
for (var i = 0; i < byteCharacters.length; i++) {
byteNumbers[i] = byteCharacters.charCodeAt(i);
}
var byteArray = new Uint8Array(byteNumbers);
var blob1 = new Blob([byteArray], {type: "application/zip, application/octet-stream"});
var fileName1 = "cool.zip";
saveAs(blob1, "my.zip");
}
Server B (request the zip file)
router.post('/getFile', (req, res, next) => {
var options = {
uri: 'Server_A_location'+ 'get_Zip',
method: 'POST,
json: req.body
}
rp(options).then(function (data) {
console.log(data)
var buff = Buffer.from(data);
res.send(buff);
}
Server A (here is the zip file)
var admzip=require('adm-zip')
router.post('/get_Zip',function(req,res,next){
var zip=new admZip();
zip.addLocalFile('..path_of_zip_file');
var zip_contents=zip.toBuffer();
res.writeHead(200,{
'Content-Disposition':'attachment; filename="myfile.zip",
'Content-Type':'application/zip'
})
return res.end(zip_contents);
Data that i receive at ServerB is in binary format: PKYUQ�3�test1/test1.1.json�}kw⸲���+...
In browser I get the zip file but its broken. Any suggestions or ideas

Multer S3 Ajax upload

I am having trouble adjusting my code to allow ajax uploads. I have the direct upload to S3 working but would like to use ajax to show upload progress.
js
$('#upload-input').on('change', function(){
var files = $(this).get(0).files;
if (files.length > 0){
var formData = new FormData();
for (var i = 0; i < files.length; i++) {
var file = files[i];
formData.append('uploads[]', file, file.name);
}
$.ajax({
type: 'POST',
processData: false,
contentType: false,
data: formData,
url: '/upload',
success : function(data){
getDetail();
console.log('picture uploaded ', data);
},
xhr: function() {
var xhr = new XMLHttpRequest();
xhr.upload.addEventListener('progress', function(evt) {
if (evt.lengthComputable) {
var percentComplete = evt.loaded / evt.total;
percentComplete = parseInt(percentComplete * 100);
$('.progress-bar').text(percentComplete + '%');
$('.progress-bar').width(percentComplete + '%');
if (percentComplete === 100) {
$('.progress-bar').html('Done');
}
}
}, false);
return xhr;
}
});
}
});
backend
setting up the variables
var aws = require('aws-sdk');
aws.config.loadFromPath('./data/s3config.json');
var multer = require('multer');
var multerS3 = require('multer-s3');
var s3 = new aws.S3({});
var upload = multer({
storage: multerS3({
s3: s3,
bucket: 'roe.pictures',
acl: 'public-read',
metadata: function (req, file, cb) {
cb(null, {fieldName: file.fieldname});
},
key: function (req, file, cb) {
cb(null, Date.now().toString())
}
})
});
Setting up post call
The issue is that I don't know how to add the files to the 'upload.array' parameter. If I load the files directly from the html form, I can just use the name of the input field. Since there is no 'req' object, I can't use req.body. Do I have to wrap this into another function?
Thanks!!
app.post('/upload', upload.array(this.body, 3), function(req, res, next) {
var newPics = [];
if(req.files) {
req.files.forEach(function(p) {
newPics.push({key : p.key, originalName : p.originalname, mimeType : p.mimetype, size : p.size})
});
Room.update({_id : req.signedCookies.prop},
{ $push: { pPics : { $each : newPics }}})
.exec(function(err, r) {
if(err) return err;
console.log('Successfully uploaded ' + req.files.length + ' files! with result ' + r);
res.redirect(req.get('referer'));
});
} else {
console.log('nothing to upload');
res.redirect(req.get('referer'));
}
});

Read files from folders inside a folder

So basically I have a folder, which holds other folders and each folder has it's own set of images, that I would like to display in a 'ul'. The problem is since I'm using readdir, which is async, how can I write the response, without getting a "Write after .end() error". Here is how my code looks like.
var fs = require('fs'),
url = require('url');
module.exports = function(req, res) {
req.pathName = req.pathName || url.parse(req.url).pathname;
if(req.pathName === '/gallery') {
fs.readdir('./content/images/public', function(err, filenames) {
if (err) {
console.log(err);
return;
}
if(filenames.length) {
var list_content = '';
for (var i = 0; i < filenames.length; i++) {
fs.readdir('./content/images/public/' + filenames[i], function(err, images) {
if (err) {
console.log(err);
return;
}
for (var i = 0; i < images.length; i++) {
list_content += '<li>' + images[i] + '</li>';
}
var list = '<ul>' + list_content + '</ul>Go back to homepage';
res.writeHead(200, {
'Content-Type': 'text/html'
});
res.send(list);
});
}
} else {
res.writeHead(200, {
'Content-Type': 'text/html'
});
res.write('<p>There are no images in the gallery</p>Go back to homepage');
res.end();
}
});
} else {
return true;
}
}
res.end();
}
});
Instead of using res.write() and res.end(), try using res.send(), which does both for you. UPDATE: Also, make sure this code is within a request callback where req, and res object is parsed correctly.
for (var i = 0; i < images.length; i++) {
list_content += '<li>' + images[i] + '</li>';
}
var list = '<ul>' + list_content + '</ul>Go back to homepage';
res.send(list);
then on the front end, receive it in the ajax response callback, like
$.post('xxxx', function(response){
alert(response); //list
});
UPDATE: after seeing your updated code,
module.exports = function(req, res) {
doesnt make sense, it needs to be something like
exports.functionName = function(req,res){
read this
https://www.sitepoint.com/understanding-module-exports-exports-node-js/
module.exports is an object of functions. Not a function. It looks like this
module.exports = {
funcExample: function() {
return 2;
},
funcOtherExample: function() {
return 1;
}

how to check the progress of file uploading using formdata in node.js?

I want to check the percentage of file uploading in the third server.
below is my controller code.
which upload the file to third server.
BASE.APP.post('/uploadFile/:request/:file', function (req, res, next) {
//var form = new BASE.multiparty.Form();
var path = 'uploads/'+req.params.file;
var fstream = BASE.FS.createReadStream(path);
//form.on('part', function(part) {
// console.log('inside');
var url = req.usersession.webipAddress;
/* var formData = {
file: {
value: BASE.FS.createReadStream(path),
options: {
fileNameUnique: req.params.file
}
}
};
// Post the file to the upload server
BASE.request.post({url: url+'test/service/uploadFile/', formData: formData});*/
/*var form = new BASE.FormData();
form.append('fileNameUnique', req.params.file);
form.append( 'file',fstream);
*/
var formData = {
fileNameUnique: req.params.file,
file: fstream
};
var r = BASE.request.post({url: url+'test/service/uploadFile/', formData: formData}, function(err1, res1, body){
console.log('new method err' + err1);
console.log('new method' + res1);
clearInterval(tasktimeoutId);
tasktimeoutId = false;
res.send(res1);
});
var tasktimeoutId = null;
if(!tasktimeoutId){
tasktimeoutId = setInterval(function(){
console.log('interval inside');
interrupttable.findOne({ "filename": req.params.file }, function(err, thor) {
if (thor!=null)
{
console.log('null inside');
if(thor.status=='interrupt')
{
console.log('interrupt');
r.abort();
r = null;
clearInterval(tasktimeoutId);
tasktimeoutId = false;
res.send("interrupted");
//return
//next(err);
}
}
});
}, 1000);
}
});
is there any way to check the file progress in percentage. So that i can
show the progress bar in front end.
Check this repo: https://github.com/zeMirco/express-upload-progress. It should have what you are looking for :)

Resources