Upload JSON data as a file - javascript

I have an object (data), and I need to convert it to JSON and upload it to a CDN. I plan to use JSON.stringify() and pass it the javascript object
It works perfectly upload files to the CDN from the browser, I wonder how I can emulate a FormData
The code I use to upload a file to the CDN is: (As an example)
const data = new FormData();
data.append('signature', auth.signature);
data.append('key', auth.id);
data.append('policy', auth.policy);
data.append('GoogleAccessId', auth.serviceAccount);
data.append('bucket', 'assets-visualive');
data.append('file', file);

After much research the solution was in Using FormData Objects in MDN
Convert the object to JSON with JSON.stringify(), then create a blob of data and upload it as a file
const object = { key: 'data', n: 10 };
const json = JSON.stringify(object);
const blob = new Blob([json], { type: 'text/json' });
const data = new FormData();
data.append('file', blob);

How do you make your ajax call? Be sure to include "processData : false" option.

Related

Does there exist a 'good-practice' way to send files without relying on FormData?

I'm currently working on an app with a React Native front-end and Node.js/Express backend. I am perfectly able to upload files using FormData with Content-Type multipart/form-data. The problem I have is that when using FormData, any other data that you wish to send in the body of the request is necessarily converted to a string. This isn't the case when one simply sends a JS object as the body of the request (as long you parse it on the backend of course). I wish to know if there is a good-practice way to send a file/files alongside JSON in a request, without losing the typings of said JSON?
Thanks
Add your data as JSON in a field of the FormData:
const data = {
foo: ["bar", 1]
};
const file = new File(["some content"], "myfile.txt");
const formdata = new FormData();
formdata.append("file", file);
// Send as JSON
formdata.append("data", JSON.stringify(data));
const req = new Request("./", { method: "POST", body: formdata });
// simulate server side getting the response
req.formData().then( (fd) => {
const received_file = fd.get("file");
// parse JSON
const received_data = JSON.parse(fd.get("data"));
console.log({ received_file, received_data });
});
When you insist on sending the image along with other data inside the JSON, then AFAIK your only option is to convert the image to some data type which can be transmitted via JSON.
The most obvious choice would be a string, and what is usually used here is the base64 encoding. It is, however, not very efficient and can cause lag.
What is sometimes done to stay within the JSON domain but still being able to upload images is to create two endpoints. One for the JSON data. One for the image upload in a binary format.

How to convert HTML5 FormData object to raw payload with frontend javascript?

In my browser side script, I want to get the entire POST request payload stream.
But when the body is a FormData object, especially when it contains a file blob, is there any easy way to make it?
The reason for doing this is that I want to make AES encrypt on the whole request body, using axios request interceptor.
For example:
I want to convert the FormData object:
const fd = new FormData()
fd.append('example.png', file) // here file is a file object from the file input object
Into the below content:
------WebKitFormBoundaryMV9GYQ2pcwRJ6XAA
Content-Disposition: form-data; name="image"; filename="example.png"
Content-Type: image/png
<<blob bytes>>
------WebKitFormBoundaryMV9GYQ2pcwRJ6XAA--
Is there any easy way to make it or any exists npm packages?
I am not sure if it will really help your end goal, but for what you ask, you can create a new Response object from this FormData and consume it as plain text:
(async () => {
const file = await new Promise((res) => document.createElement('canvas').toBlob(res));
const fd = new FormData();
fd.append('example.png', file, 'example.png');
const resp = new Response(fd);
console.log( await resp.text() );
})();

How to send formData object as key value pair in Vue js?

I am trying to upload an image with vue and laravel on backend. Everything was going well until I ran into a problem. My image gets sent when i make an axios call sending formData only as an argument.
let formData = new FormData();
formData.append("image", this.image);
axios.post('url',formData)
But on axios request I want to send an object, not just the formData, something like this:
const myObj={ name:'hello','shop_id':2, image:formData }
axios.post('url',myObj)
But this doesn't work. Is there any way I can work around with this?
Add the name and shop_id values to the FormData object. In this case FormData is the container in which you can send all of your data.
let formData = new FormData();
formData.append('image', this.image);
formData.append('name', 'hello');
formData.append('shop_id', 2);
axios.post('url',formData)
If your data becomes more complex and you need to send a big object with loads of data, then you could send the the object as a JSON value in one of the keys.
const complexObject = {
...loads of data here
};
formData.append('complexObject', JSON.stringify(complexObject))
Parse the JSON back to usable code on the server side to use the data inside the complex object.

Sending a file stream in JSON

Can I send the stream of data from a File or Blob and post it in JSON in Angular 5?
I tried using a FileReader, but not able to get the stream out of it using the
result property.
let blobfile=new Blob([this.curResume]);
let fr=new FileReader;
fr.readAsText(blobfile);
console.log(fr,fr.result);
This is how I've tried it and this is what I get in the console.
console output
I understood that you are trying to push a file to the server using POST API call. In that case you can pass it as formData.
Please be a little eloborate on adding your question.
const fileData= new Blob([this.yourFile], { type: "<your File type>" });
const formData = new FormData();
formData.append("yourFile", fileData);
this.httpClient.post(<your url>, formData);

Simple async image upload for Express?

I'm using a button click to trigger a file input dialog. Once the file is selected, I'm displaying the thumbnail in a preview.
const uploadListener = function() {
const preview = document.getElementById('preview')
const uploadBlob = window.URL.createObjectURL(this.files[0])
preview.style.backgroundImage = `url(${ uploadBlob })`;
}
const fileUploader = document.getElementById('fileUpload')
fileUploader.addEventListener('change', uploadListener)
From here, what's the easiest way to get the file at uploadBlob asynchronously sent (via XMLHttpRequest()?) to my node.js Express server and saved to the server?
I've written this out with a base64 encoded FileReader() in the past, where you have to filter out the metadata, then decode to a binary file and figure out the name + extension on the server, but it was slow and seemed sort of obscure.
It's misleading to name the variable uploadBlob since it's not a blob any more. it's a url, you don't send that to the server.
Basically, append the blob/file to a FormData, then send the formdata in your ajax request
const fd = new FormData()
fd.append('avatar', this.files[0])
// fd.append('avatar', this.files[0], optionalFileName)
fetch(uploadUrl, {method: 'post', body: fd})
/*
or using XMLHttpRequest:
var xhr = new XMLHttpRequest
xhr.open('POST', uploadURL)
xhr.send(fd)
*/

Categories

Resources