I want to know the easiest way to handle two separate file uploads, one for images and the other for audio. right now I am using multer and it uploads all multipart uploads to the same location. can I specify different locations for both file uploads?
Assuming you want to save the files to disk, you can do something like this:
var storage = multer.diskStorage({
destination: function(req, file, cb) {
if (file.fieldname === 'image-file') {
return cb(null, 'folder-for-image-uploads');
}
if (file.fieldname === 'audio-file') {
return cb(null, 'folder-for-audio-uploads');
}
cb(new Error('Unknown fieldname: ' + file.fieldname));
},
filename: function(req, file, cb) {
if (file.fieldname === 'image-file') {
return cb(null, 'image-filename.jpg');
}
if (file.fieldname === 'audio-file') {
return cb(null, 'audio-filename.mp3');
}
cb(new Error('Unknown fieldname: ' + file.fieldname));
}
});
var upload = multer({storage: storage});
app.post('/endpoint', upload.fields([{name: 'image-file', maxCount: 1}, {name: 'audio-file', maxCount: 1}]), function(req, res) {
// handle request, files already saved to disk
res.sendStatus(200);
}
For this to work, you need the name of input HTML elements to match the fieldname property, e.g.:
<form method="POST" action="/endpoint" enctype="multipart/form-data">
<input type="file" name="image-file">
<input type="file" name="audio-file">
<input type="submit">Submit</input>
</form>
Related
I'm uploading local images to a remote server using TinyMCE's images_upload_handler. This works fine, that is, the image is uploaded, but the HTML that TinyMCE returns will not seem to accept any src reference that contains http. I'm integrating TinyMCE as part of KeystoneJS, so perhaps there's something in the connection that's sanitising the HTML, but I'm a bit stumped.
My images_upload_handler is
images_upload_handler: function (blobInfo, success, failure) {
var xhr, formData;
console.warn('!!!!');
xhr = new XMLHttpRequest();
xhr.withCredentials = false;
xhr.open('POST', 'http://localhost:4545/tinymceimage');
xhr.onload = function() {
var json;
if (xhr.status != 200) {
failure('HTTP Error: ' + xhr.status);
return;
}
json = JSON.parse(xhr.responseText);
if (!json || typeof json.location != 'string') {
failure('Invalid JSON: ' + xhr.responseText);
return;
}
console.log('json.location',json.location);
success(json.location);
};
formData = new FormData();
formData.append('file', blobInfo.blob(), blobInfo.filename());
xhr.send(formData);
}
and my server handler is
app.post('/tinymceimage', function tinyMCEUpload(req, res) {
console.log('files', req.files);
if (!req.files || Object.keys(req.files).length === 0) {
return res.status(400).send('No files were uploaded.');
}
// The name of the input field (i.e. "sampleFile") is used to retrieve the uploaded file
let sampleFile: UploadedFile = req.files.file as UploadedFile;
// Use the mv() method to place the file somewhere on your server
console.log(sampleFile.name);
const out = path.resolve(__dirname, '../../static_files', sampleFile.name);
fs.writeFile(out, sampleFile.data, 'base64', function(err) {
if (err) console.log(err);
if (err) res.send(err);
res.json({ location: `http:localhost:4545/${sampleFile.name}` });
});
});
but the HTML returned from TinyMCE does not contain correct image src's, for instance NOT
<img src="http://localhost:4545/blop.jpg" />,
but rather
<img src="../../blop.jpg" />
If I change
res.json({ location: `http:localhost:4545/${sampleFile.name}` });
to
res.json({ location: `something/${sampleFile.name}` });
I get
<img src="something/blop.jpg" />
I have a small HTML template and what I want is to upload image from one location to another. After selecting and clicking on the upload button, response gives me "Uploaded successfully" But the image is not in the destination folder. Please look into the below code.
HTML
<form id="frmUploader" enctype="multipart/form-data" action="book/api/Upload/" method="post">
<input type="file" name="imgUploader" multiple />
<input type="button" name="submit" id="btnSubmit" value="Upload" onclick="upload()"/>
</form>
index.js
function upload() {
axios.post(baseUrlLocal+'/book/api/Upload', {headers: headers})
.then(response => {
console.log(response.data.success)
if (response.data.success) {
console.log("hi: "+response)
// $.notify("New Book is Added to your Library", "success");
}
})
.catch(function (error) {
console.log(error)
// $.notify("Please check all the details","warn");
});
}`
book.js
var Storage = multer.diskStorage({
destination: function(req, file, callback) {
callback(null, "../public/images/");
},
filename: function(req, file, callback) {
callback(null, file.fieldname + "_" + Date.now() + "_" +
file.originalname);
}
});
var upload = multer({
storage: Storage
}).array("imgUploader", 3);
router.get("/image", function(req, res) {
res.sendFile(__dirname + "/index.html");
});
`router.post("/api/Upload", function(req, res) {
upload(req, res, function(err) {
if (err) {
return res.end("Something went wrong!");
}
return res.end("File uploaded sucessfully!.");
});
});`
My html code is
<form action="/file_upload" method="POST" enctype="multipart/form-data">
<input type="file" name="photos" id="photos" accept='image/*' multiple>
<input type="submit" value="Upload" id="upload_my_photos" disabled>
</form>
In sails I am using
uploadFiles = req.file("photos");
This is only fetching just single file.
Edit : I would also like to save the individual files. Below is the code I am using but no files are getting uploaded:
req.file('photos').upload(function (err, uploadedPhotos) {
if (err) return res.serverError(err);
async.eachSeries(uploadedPhotos,
function (uploadedFile, callback) {
sails.log("upload file size and name is " + uploadedFile.size + " " + uploadedFile.filename);
req.file(uploadedFile).upload({
dirname: "path/to/directory",
// saveAs: function (file, cb) { cb(null, file.filename); }
},
function onUploadComplete(err, files) {
if (err) return res.serverError(err);
if (files.length === 0) {
return res.badRequest('No file was uploaded');
}
sails.log("files uploaded");
});
}, function (err) {
// if any of the saves produced an error, err would equal that error
if (err) {
console.log(err);
} else {
return res.status(200).send({ success: false, message: "failed to upload" });
}
});
});
Sails req.file() is representing an incoming multipart file upload from the specified field.
You need to subscribe to the request with a callback in which the uploaded files will be passed as an second argument:
req.file('photos').upload(function (err, uploadedPhotos){
if (err) return res.serverError(err);
return res.json({
message: uploadedPhotos.length + ' file(s) uploaded successfully!',
files: uploadedPhotos
});
});
I'm getting req.file as undefined. I have tried everything. I have searched for other solutions, but it's not a problem in input name="avatar" attr and upload.single("avatar").
Also, I'm getting an error in the console:
Error for image upload 400 - Bad Request
{"code":"ER_PARSE_ERROR","errno":1064,"sqlMessage":"You have an error
in your SQL syntax; check the manual that corresponds to your MySQL
server version for the right syntax to use near '?)' at line
1","sqlState":"42000","index":0,"sql":"INSERT INTO avatars (image)
VALUES(?)"}
I would say that it is because req.file is undefined.
Please, help me to understand what I'm doing wrong.
api.js:
var storage = multer.diskStorage({
destination: function(req, file, callback) {
callback(null, "./assets/images/uploads");
},
filename: function(req, file, callback) {
callback(null, file.fieldname + "_" + Date.now() + "_" +
file.originalname);
}
});
var upload = multer({
storage: storage,
limits: {fileSize: 1000000},
fileFilter: function(req, file, cb) {
checkFileType(file, cb);
}
});
function checkFileType(file, cb) {
const filetypes = /jpeg|jpg|png|gif/;
const extname = filetypes.test(file.originalname.toLowerCase());
const mimetype = filetypes.test(file.mimetype);
if(extname && mimetype) {
return cb(null, true);
} else {
cb('Error: Images only');
}
}
router.post("/upload", upload.single('avatar'), function(req, res) {
console.log(req.file); // <- ALWAYS UNDEFINED
pool.getConnection(function(err, connection) {
if (err) throw err;
connection.query('INSERT INTO avatars (image) VALUES(?)', req.file,
function (error, results, fields) {
if(error){
console.log("Error: " + error);
res.status(400).send(error);
}
res.status(200).end(JSON.stringify(results));
connection.release();
if (error) throw error;
});
});
});
html:
<form enctype="multipart/form-data">
<input class="form-control"
(change)="onFileSelected($event)"
type="file" name="avatar">
<button type="submit" class="btn btn-danger float-right" (click)="onUpload()">Upload image</button>
</form>
ctrl:
onFileSelected(event) {
if(event.target.files.length > 0) {
this.uploadImage = <File>event.target.files[0];
}
}
onUpload() {
if(this.uploadImage) {
this.friendService.uploadFile(this.uploadImage)
.subscribe(
data => {
return true;
},
error => {
console.error('Error for image upload ' + error);
return false;
})
}
}
service:
uploadFile(file): Observable<any> {
return this.http.post(`${this.apiUrl}/upload`, file)
.map(res => res.json())
.catch(this.handleError);
}
db mysql avatars table:
Field - image
Type - blob
Null - NO
Key Default Extra - Empty
while uploading file it should be form data and content type should be multipart/form-data
For your reference: File Upload In Angular?.
I hope this will help you.
I am uploading file through my rest mean application, but i am not able to retrieve it back from backend . how do i retrieve it,
Here is upload code
var storage = multer.diskStorage({
destination: function (req, file, callback) {
callback(null, './uploads');
},
filename: function (req, file, callback) {
callback(null, mongoose.Types.ObjectId() + '-' + file.originalname);
}
});
var upload = multer({ storage : storage }).array('userPhoto',10);
upload(req,res,function(err) {
console.log(req.files);
var images =[];
for(var i=0; i<req.files.length; i++){
images[i]=req.files[i].path;
}
var newalbum = new albummodel({
image:images
});
newalbum.save(function(err, albm) {
if(err) {
res.json({success: false, msg: 'can't store.'});
} else {
console.log(albm);
}
});
if(err) {
return res.end("Error uploading file.");
}
res.end("File is uploaded");
});
Here is my retrieve code
albummodel.findOne({_id:req.params.id},function(err, docs){
res.json(docs);
})
This whole discussion help you. Please refer it.
https://github.com/Automattic/mongoose/issues/3079