Hey I am creating image upload functionality in my application using formidable module.It works fine when uploading image but I want to perform some validation on it like checking image type and image size but I'm not getting a way to validate size of image.
I don't want user to upload image more than 1Megabyte.
router.post('/upload',function(req,res,next){
var types = ['image/jpeg','image/png'];
var error = true;
var form = new formidable.IncomingForm();
form.uploadDir = path.join(__dirname,'../public/images/profile');
form.on('fileBegin',function(name,file){
var type = types.find(type => type == file.type);
if(!type){
throw "Image should be in jpeg or png format.";
}
});
form.on('file',function(name,file){
fs.rename(file.path,path.join(form.uploadDir,file.name),function(err){
if(err) console.log(err);
});
});
form.on('error',function(err){
if(err) console.log("Error");
});
form.on('end',function(){
if(!error) console.log("updated");
});
form.parse(req);
});
Related
--expo managed react native application--
--android--
--internal distribution--
I am uploading local mp4's to an s3 bucket with aws-sdk.
It requires I put data into blob format before I push to s3 with AWS.S3.putObject(params).
const uploadFile = async (file) => {
let blob
let response
try{
response = await fetch(location);
}
catch(e){console.log('fetch error', e)}
try {
blob = await response.blob();
}
catch(e){console.log('Blobify Error:', e)}
The above code works to fetch and blob mp4 video files from a local uri, as the aws sdk requires blobs. For some reason if the mp4 file is greater than ~190mb, the same code fails with a network request failed error, generated from the fetch request. To be clear the code fails during the local fetch before it can be passed to the aws-sdk to uploaded.
After reading several tutorials and feedback, although no one has mentioned the size issues I am experiencing. I experimented with rewriting the code using xmlHttpRequest() as below. It also succeeds for all files below ~190 megabytes and fails for anything above 190mb. Once again it fails locally before it can be .blob() and passed to aws-sdk.
let makeBlob
try{
makeBlob = (url)=> {
return new Promise((resolve, reject) => {
var xhr = new XMLHttpRequest();
xhr.onerror = reject;
xhr.onreadystatechange = () => {
if (xhr.readyState === 4) {
resolve(xhr.response);
}
};
xhr.open('GET', url);
xhr.responseType = 'blob'; // convert type
xhr.send();
})
}
}catch(e){console.error('blob fail:', e)}
So as a recap separate protocols for fetching a uri both fail in the same way, I would accept other options for converting my uri to blob format or some ideas of what is causing this failure.
I'm using a Circuit JS SDK and want to send message with attached image. I found on documentation that I should set the item.attachments to File[] object. But how can I do it if I have only image URL (like https://abc.cde/fgh.png)?
To be able to post an image in a conversation, the image needs to be uploaded to Circuit which is done internally in the addTextItem API as you already found out. And yes this API takes an array of File objects.
You will need to download the image via XMLHttpRequest as blob and then construct a File object.
const xhr = new XMLHttpRequest();
xhr.responseType = 'blob';
xhr.open('GET',<url of image> , true);
xhr.onreadystatechange = async () => {
if (xhr.readyState == xhr.DONE) {
const file = new File([xhr.response], 'image.jpg', { lastModified: Date.now() });
const item = await client.addTextItem(convId.value, {
attachments: [file]
});
}
};
xhr.send();
Here is a jsbin https://output.jsbin.com/sumarub
I am trying to using React-Native-Camera to capture an image and upload to the server, the captured response only provide base64 image and relative uri path to the system's cache. I used to turn the image to a blob in websites using packages like blob-util, which doesn't work on React-native.
As I was searching around I see that most people are uploading the base64 strings directly to the server, but I can't find anything about blob, how can I get a blob from base64 image string?
I have a function in my project to convert image to a blob. Here it is. 1st function is to handle the camera. 2nd fuction is to create a blob and a image name.
addPicture = () => {
ImagePicker.showImagePicker({ title: "Pick an Image", maxWidth: 800, maxHeight: 600 }, res => {
if (res.didCancel) {
console.log("User cancelled!");
} else if (res.error) {
console.log("Error", res.error);
} else {
this.updateProfilePicture(res.uri)
}
});
}
This addPicture is used to launch the image picker. In above function, res means the output, that comes from showImagePicker. I had to pass the uri prop of the result(res.uri) to below function, in order to create the blob file
In below function, I wanted to name the image with userId. You can use anything you like.
updateProfilePicture = async (uri) => {
var that = this;
var userId = this.state.user.uid
var re = /(?:\.([^.]+))?$/;
var ext = re.exec(uri)[1];
this.setState({
currentFileType: ext
});
const blob = await new Promise((resolve, reject) => {
const xhr = new XMLHttpRequest();
xhr.onload = function () {
resolve(xhr.response);
};
xhr.onerror = function (e) {
console.log(e);
reject(new TypeError('Network request failed'));
};
xhr.responseType = 'blob';
xhr.open('GET', uri, true);
xhr.send(null);
});
var filePath = userId + '.' + that.state.currentFileType;
}
There are some other codes in above function, which are using to uplad the image to firebase storage. I did not include those codes.
I am using puppeteer and I have a requirement where I have to upload screenshot on S3.
I am using fetch PUT api with signed url and my image is png format.
Everytime I am getting an error 'failed to fetch'. I have tried keeping image inmemory and in local storage but neither of them working.
await page.evaluate(async(signedUrl,screenshot) =>{
(function generateXHRRequest(){
var xhr = new XMLHttpRequest();
xhr.withCredentials = true;
xhr.onreadystatechange = function () {
if (xhr.readyState === 4 && xhr.status === 200) {
console.log(JSON.stringify(xhr.response));
}
};
xhr.open("PUT", signedUrl);
xhr.setRequestHeader("Cache-Control", "no-cache");
xhr.setRequestHeader('Content-Type', 'image/png');
xhr.setRequestHeader('Accept', 'image/png');
xhr.setRequestHeader('Access-Control-Allow-Origin','*');
xhr.setRequestHeader('Access-Control-Allow-Credentials', 'true');
xhr.send(screenshot.data);
})();
},signedUrl,screenshot);
})
I have captured screenshot and kept it in memory. Now passing that to the above function.
Here byte array is copied to file as text and from S3 , when i download file manually, '.txt' file is downloaded.
I'm trying to upload a file (an image), the upload is fine, the file is stored in Mongo and have the same content type and same size as the original file, then when I try to download it, the file is corrupted but keeps the same content type (if I upload a pdf, it is recognized as a pdf, if it is a png, it is also recognized, but I can't open them).
I don't understand what is wrong with this, it is pretty simple and standard.
For the upload from the client, I use angular ng-upload, for the download, it is a simple GET request to the route defined in the code.
EDIT :
The file is well uploaded on the server, so the problem is when I try to read it from GridFS.
The file that is downloaded is bigger than the one uploaded ! So the file isn't as the original and is corrupted, why ?
Here is my code.
//BACKEND
//ROUTES
var multer = require('multer');
var upload = multer({ dest: './tmp/'});
router.post('/:id/logo',upload.single('file'), uploadFile);
router.get('/:id/logo', getFile);
//Controller
var Grid = require('gridfs-stream');
var mongoose = require('mongoose');
var fs = require('fs');
uploadLogo = function(req, res) {
var gfs = Grid(mongoose.connection.db, mongoose.mongo);
var writeStream = gfs.createWriteStream();
fs.createReadStream(req.file.path).pipe(writeStream);
writeStream.on('close', function(file) {
res.status(200).send({fileId: file._id});
});
writeStream.on('error', function(e) {
res.status(500).send("Could not upload file");
});
}
getFile = function(req, res) {
var gfs = Grid(mongoose.connection.db, mongoose.mongo);
// Check if the file exist
gfs.findOne({ _id: req.params.id}, function(err, file) {
if(err) {
res.status(404).end();
} else if(!file){
res.status(404).end();
} else {
var readstream = gfs.createReadStream({
_id: file._id
});
res.set('Content-Type', file.contentType);
readstream.on('error', function (err) {
res.send(500, err);
});
readstream.on('open', function () {
readstream.pipe(res);
});
}
});
}
//FRONT END
$scope.newFileUpload = function(file) {
$scope.upload(file);
}
$scope.upload = function(file) {
if (file && !angular.isUndefined(file.name)) {
Upload.upload({
url: 'api/' + $scope.myId + '/logo',
fields: {
'type': 'logo'
},
file: file
}).success(function(data, status, headers, config) {
$scope.imageId = data.fileId;
}).error(function(data, status, headers, config) {
console.log('file upload error status: ' + status);
});
}
};
//THE HTML
<div class="drop-box"
ngf-drop
ngf-select
ng-model="imageLogo"
ngf-drag-over-class="dragover"
ngf-allow-dir="true"
accept="image/*"
ngf-pattern="'image/*'"
ngf-change="newFileUpload(imageLogo)"
ngf-multiple="false"
ngf-resize="{width: 200, height: 50}">
Drop logo image here or click to upload</div>
<input type="file" nv-file-select uploader="uploader"/>