I wanted to have a way so users can choose images to send with a review.
so I use dropzone.js . It seems like having problems sending multiple images in one request. I thought that req.files would contain an array of files but that didn't happen. right now I see a problem because dropzone adds [] with the indexes inside for the name param.
when adding to images to dropzone I see something like this in request payload:
------WebKitFormBoundaryJOpGX6kWaoknKhIN
Content-Disposition: form-data; name="images[0]"; filename="data.png"
Content-Type: image/png
------WebKitFormBoundaryJOpGX6kWaoknKhIN
Content-Disposition: form-data; name="images[1]"; filename="loginButton.png"
Content-Type: image/png
------WebKitFormBoundaryJOpGX6kWaoknKhIN--
I feel like [0] and [1] is causing me problems
server:
app.post("/files" , upload.array("images"), (req, res) =>{
console.log("hit here")
console.log("req.file :", req.file)
// console.log(req.body)
console.log(req.files)
res.send("ok")
})
simple multer: I had more complicated one before
var upload = multer({ dest: "./uploads" })
frontend:
<script src = "/dropzone.js"></script>
<script>
$(function(){
Dropzone.autoDiscover = false;
var myDropZone = new Dropzone(".dropzone", {
url : "/files",
// uploadMultiple : true,
autoProcessQueue : false,
parallelUploads: 5,
paramName: "images",
uploadMultiple: true,
init : function(){
this.on("success", function(){
// alert("success")
})
this.on("sendingmultiple", function(){
console.log("SENDING MULTIPLE");
})
this.on("errormultiple", function(files, response){
console.log("ERROR");
console.log(response);
console.log(files);
})
}
})
$("#skip, #login").on("click", function(e){
myDropZone.processQueue();
})
})
</script>
<div class = "dropzone"></div>
<div id = "skip"> skip </div>
<div id = "login">login</div>
when I get rid of uploadMultiple: true, I get the images in the FS but it looks like multiple post request were made there is no req.files array with multiple images. I thought there would be
You should be able to force the name by specifying a function for paramName instead of a string:
paramName: function() { return 'images'; },
which will prevent any suffixes from being added to the form fields.
Related
I am trying to intergrate File Pond with my Flask server and I can not find the unique file id it sends with requests. With normal uploads it will show me request data on the server, but without the unique ID I am looking for. I want to use this unique ID to attach to a database in order to delete the file if the revert is sent later.
Going over the docs, it is suppsoed to send a unique ID with every upload, but I can't tell if it's a bad config in file pond or I suck at reading request.files. Just ignore all my prints where I try to read the contents of request.
Here is my FilePond Config:
FilePond.setOptions({
//allowImageEdit: true,
//allowImageCrop: true,
//allowMultiple: true,
//allowFileEncode: true,
allowImageExifOrientation: true,
credits: false,
server: {
process: {
url: './pondupload',
method: 'POST',
headers: {
'x-customheader': 'Hello World',
},
withCredentials: document.getElementById('csrf_token'),
onload: (response) => response.key,
onerror: (response) => response.data,
ondata: (formData) => {
formData.append('csrf_token', document.getElementById('csrf_token').value)
return formData;
},
},
revert: './pondupload',
restore: './restore/',
load: './load/',
fetch: './fetch/',
},
});
Here is my route in flask:
#bp.route('/pondupload', methods=['POST', 'DELETE'])
def pondupload():
print ('data: '+str(request.data))
print('form: '+str(request.form))
print('files: '+str(request.files))
print('args: '+str(request.args))
form=EmptyForm()
#TODO add csrf to revert
if request.method == "DELETE":
print('delete stuff')
if request.method == "POST" and form.validate_on_submit():
upload_dir = current_app.config['UPLOAD_FOLDER']
fn = ""
file_names = []
# get file object from request.files (see: http://flask.pocoo.org/docs/1.0/api/#flask.Request.files)
for key in request.files:
print('key: '+str(key))
file = request.files[key]
fn = secure_filename(file.filename)
if allowed_file(fn) == True:
file_names.append(fn)
try:
file.save(os.path.join(upload_dir, fn))
return jsonify({}), 200
except:
return jsonify(filename=file_names), 402
return jsonify({}), 400
I am trying to send an image through a resource and recovery in a php file but I have not succeeded, this is my JS file:
//* AJAX *//
startAsyncNews: function(){
if(this.sendimage){
var formdata = new FormData();
formdata.append("file",this.contentnew.imageFile );
console.log(this.contentnew.imageFile);
}
// POST /someUrl
this.$http.post('controllers/newsController.php', {
data:{action : this.accion_new, data_new: this.contentnew , imgf : formdata}
}).then(response => {
}, response => {
console.log("error");
});
},
imageSelect: function($event){
this.sendimage=true;
this.contentnew.imageFile =$event.target.files[0];
}
When I use the console.log = console.log (this.contentnew.imageFile), it shows me the properties of the image correctly, that is, it is sending the file well, but when I receive it in php and I do vardump I get this object ( stdclass) # 3 (0) no properties no properties and with json_decode / encode I get it empty, also try
headers: {
'content-type': 'multipart/form-data'
}
But it generates the following error:
Missing boundary in multipart/form-data POST
You need to add all your data in formdata Object using formdata.append(key,value) function.
Then you simply send formdata
formdata.append('action ',this.accion_new);
formdata.append('data_new',this.contentnew);
this.$http.post('controllers/newsController.php', {
data:formdata
});
// or just if i'm not mistaken
this.$http.post('controllers/newsController.php',formdata);
object in http request data.
I don't know what this.accion_new and this.contentnew are, but this line:
this.$http.post('controllers/newsController.php', {
data:{action : this.accion_new, data_new: this.contentnew , imgf : formdata}
})
should simply be be:
this.$http.post('controllers/newsController.php', formdata)
I have a dropzone setup with the following script:
<script>
Dropzone.options.myDropzone = {
url: 'assets/PHP/createNieuws.php',
autoProcessQueue: false,
uploadMultiple: true,
parallelUploads: 1,
maxFiles: 1,
maxFilesize: 1,
acceptedFiles: 'image/*',
addRemoveLinks: true,
createImageThumbnails: true,
init: function () {
dzClosure = this; // Makes sure that 'this' is understood inside the functions below.
this.on("success", function (file, responseText) {
console.log(responseText);
});
// for Dropzone to process the queue (instead of default form behavior):
document.getElementById("submit").addEventListener("click", function (e) {
// Make sure that the form isn't actually being sent.
e.preventDefault();
e.stopPropagation();
if (dzClosure.getQueuedFiles().length > 0) {
dzClosure.processQueue();
} else {
dzClosure.uploadFiles([{ name: 'nofiles' }]); //send empty
}
});
//send all the form data along with the files:
this.on("sendingmultiple", function (data, xhr, formData) {
formData.append("titel", jQuery("#titel").val());
formData.append("artikel", jQuery("#artikel").val());
});
}
}
</script>
And i also have a file named default.png on my server. I would like dropzone to refer to default.png if no image is detected. As you can see i've tryed this solution already to no succes: https://stackoverflow.com/a/41044001/6396380
This returns the following error in my chrome console:
dropzone.js:1497 Uncaught TypeError: Cannot read property 'filename' of undefined
My dropzone version is 5.1.0 .
Any idea's on how to fix this?
This happens because the new version assumes that there is a file.upload object with filename. Changing your mock file to
{ name: 'nofiles', upload: { filename: 'nofiles' } }
should do the trick.
You should also upgrade to 5.1.1 because it solves a bug related to this.
For people having errors on firefox due to append method while using uploadFiles function but still wants to get that phat xhr request submitted with everything handled for you I suggest instead of using
dropzone.uploadFile({
name: 'nofiles',
upload: {
filename: 'nofiles'
}
})
to use
dropzone._uploadData(
[
{
upload: {
filename: ''
}
}
],
[
{
filename: '',
name: '',
data: new Blob()
}
]
);
A web page (front) is calling a service which send a PDF stream as a response :
Here is the front code :
'click .btn': function (event) {
/.../
event.preventDefault();
Http.call(params, (err, res) => { // callback
if (err) console.log(err); // nothing
console.log({ res }); // print below result
const blob = new Blob(
[res.content],
{ type: `${res.headers['content-type']};base64` }
);
saveAs(blob, res.headers['content-disposition'].slice(21));
});
}
Here is the response from the server ( console.log(res) ) : { res : Object } printed in the console.
content: "%PDF-1.4↵1 0 obj↵<<↵/Title (��)↵/Creator (��)↵/Prod ..... lot of characters....%"
data: null,
statusCode: 200,
headers: {
connection: "close",
content-disposition: "attachment; filename=myDoc.pdf"
content-type: "application/pdf",
date: "date",
transfer-encoding: "chunked",
x-powered-by: "Express"
}
However, the PDF is downloaded with no content, it's full blank like corrupted ( But I can see the content in the string ). It works well with the CSV routes ( I send a csv as a stream and download it with the same method and I got the data).
I think there is something with the format %PDF ...% but I didn't manage to find something.
Note : With postman, it works, my PDF is saved, the page is not blank, I got the data. So there is something in the front I am not doing right.
I also tried with :
const fileURL = URL.createObjectURL(blob);
window.open(fileURL); // instead of saveAs
but the result is the same ( but in another tab instead of saved PDF ) blank page.
Any ideas ?
You probably forgot to specify the response type in your inital backend call - from the example you posted "arraybuffer" would be the correct one here, you can check all types here.
I'm writing this web-page in angularJS where I want people to edit and store text and images. I've created a file uploading function that let's you upload files from the users computer. The problem is getting this file stored into mongoDB. I've read alot of examples on gridFS but none of them quite matched what I'm trying to do.
Here's my code:
web-server.js:
app.post('/uploadFile', function(req,res){
console.log("Retrieved:");
console.log(req.files);
var Grid = require('gridfs-stream');
var gfs = Grid(DB, mongoose.mongo);
// streaming to gridfs
var writestream = gfs.createWriteStream(req.files.file);
fs.createReadStream(req.files.file.path).pipe(writestream);
services.js:
function uploadFilesToServer(file){
var fd = new FormData();
fd.append("file", file);
var deferred = $q.defer();
console.log("trying to save:");
console.log(file);
$http({
method:"POST",
url: "uploadFile",
data: fd,
withCredentials: true,
headers: {'Content-Type': undefined },
transformRequest: angular.identity
}).success(function(data){
var returnValue = [true, file, data];
deferred.resolve(returnValue);
}).error(function(data){
var returnValue = [false, file, data];
deferred.resolve(returnValue);
});
return deferred.promise;
}
At the moment I'm not getting any error messages when I run the code, but neither is the images stored in the db.files or db.chunks. Any help is appreciated.
GridFS-stream usually stores it's data in db.fs.files/db.fs.chunks if not set by the user.
To change this, you'll have to add:
{
....
root: 'my_collection'
....
}
to gridfs-stream options.
From NPM docs.:
createWriteStream
To stream data to GridFS we call createWriteStream passing any options.
var writestream = gfs.createWriteStream([options]);
fs.createReadStream('/some/path').pipe(writestream);
Options may contain zero or more of the following options...
{
_id: '50e03d29edfdc00d34000001', // a MongoDb ObjectId
filename: 'my_file.txt', // a filename
mode: 'w', // default value: w+, possible options: w, w+ or r,
see [GridStore]
(http://mongodb.github.com/node-mongodb-native/api-generated/gridstore.html)
//any other options from the GridStore may be passed too, e.g.:
chunkSize: 1024,
content_type: 'plain/text',
// For content_type to work properly, set "mode"-option to "w" too!
root: 'my_collection',
metadata: {
...
}
}
See https://www.npmjs.org/package/gridfs-stream for more.