Fetch Put API to upload image using signed url - amazon-s3

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.

Related

In react native Fetch(localUri) throws error: network request failed. Only on file sizes larger then 195 mb

--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.

Upload a local image file via puppeteer connect on Chrome extension

Task: I'm building a chrome extension with a popup (panel_chatwindow.js) window (standalone window). I want to take a local image file (e.g., /1.png) and upload it to a website that has a <input type='file'/> element (e.g., any services that require to upload a user photo).
Note
Other than upload file, the code can execute other web macro just fine.
My current code:
let browserWSEndpoint = "";
const puppeteer = require("puppeteer");
async function initiatePuppeteer() {
await fetch("http://localhost:9222/json/version")
.then((response) => response.json())
.then(function (data) {
browserWSEndpoint = data.webSocketDebuggerUrl;
})
.catch((error) => console.log(error));
}
initiatePuppeteer();
$("#puppeteer-button").on("action", doPuppeteerThings);
// Assign button to puppeteer function
async function doPuppeteerThings(event, actionArray) {
const browser = await puppeteer.connect({
browserWSEndpoint: browserWSEndpoint,
});
const page = await browser.newPage();
await page.setViewport({
width: 1600,
height: 1000,
});
await page.goto("website", {
waitUntil: "networkidle2",
});
await page.waitForSelector("input[type=file]");
await page.waitFor(2000);
const input = await page.$('input[type="file"]');
await input.uploadFile("/1.PNG");
})
Error message on popup window console (panel_chatwindow.js)
panel_chatwindow.js:160 is the await input.uploadFile("/1.PNG"); line
Using puppeteer.launch works perfectly fine with the code, i.e., can upload a local file to a website once launching the node server.
I don't have to use puppeteer to upload image files, any other way on chrome extension would be just fine.
I'm aware of this post: https://github.com/puppeteer/puppeteer/issues/4405 but i am not able to address my issue with any answers in the thread.

Send image in attachments by URL in Circuit JS SDK

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

How do I convert base64 string image to blob in React Native?

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.

Delete uploaded file with formidable

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);
});