banner



How To Upload File In Google Form

Uploading files using Base64 encoding is a common practice, the usage of the technique has been increased since React and Vue.js like frameworks gained popularity.

In this guide I'm going to evidence you how to upload files using base64 encoding

What's Base64 Encoding?

Base64 is a encoding algorithm that allows you to transform whatsoever characters into an alphabet which consists of Latin letters, digits, plus, and slash. You can catechumen images into a "readable" string, which can be saved or transferred anywhere.

To understand it amend I recommend y'all to have a look at that wonderful commodity from base64.guru and What is Base64 Encoding past Akshay Kumar

What's Information URI?

We tin can't but send the Base64 string to our server and process it, what makes it different than any other string? How do you know the file is a image or PDF file? That's where Data URI comes in.

Data URI or Data URL is a format that nosotros can apply some information as an inline string. In order to process our Base64 data in server we demand to know the mime type (which can be tricked), which Data URI format provides this.

This is the Data URI or Information URL format:

          data:[<mime type>][;charset=<charset>][;base64],<encoded information>                  

For example this a Base64 string wrapped every bit a Data URI:

          <img src="information:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD/2wCEAAoHCBUWFRgVFRYZGRgZHBgYGBwYGhgYGBoYGBgaGhoZGBgcIS4lHB4rIRgYJjgmKy8xNTU1GiQ7QDs0Py40NTEBDAwMEA8QHBISGjQh...3000 more characters" />                  

The output:

Uncle Ben afterward Base64

Final Outcome

You tin take a look at this sandbox for the final event for front end-end:

Create your HTML Form

Permit'southward create a very simple class, we are going to handle it with Javascript

          <class id="formcarryForm">  	<label for="nameInput">Name</label>  	<input type="text" id="nameInput" />  	<label for="messageInput">Message</label>  	<textarea id="messageInput" cols="30" rows="two"></textarea>  	<input type="file" id="pictureInput" />    	<push button blazon="submit">Submit</button> </form>                  

Add together your Javascript code

In order to upload files every bit Base64, nosotros need to listen the change issue of our file input, and the process is async and so we need to hold some land to determinate whether we can submit the form or not.

Let's start with our file input.

          const fileInput = document.getElementById('pictureInput')  // This is for storing the base64 strings permit myFiles = {} // if yous expect files by default, brand this disabled // we volition wait until the last file being candy allow isFilesReady = true  fileInput.addEventListener('alter', async (result) => {   const files = upshot.srcElement.files;    console.log(files) })                  

Nosotros are going to employ isFilesReady later on to check if the async process has been completed or non, it's true by default considering there are no files in the input when the page loads, if you desire to brand it required yous tin change it to isFilesReady = imitation

Let's try what happens:

As you can see, we can admission our files, now it's time for the fun function.

Converting input file to base64 string

Nosotros are going to use native FileReader API to read files from the input

          fileInput.addEventListener('change', async (event) => {   // make clean upwards primeval items   myFiles = {}   // prepare state of files to imitation until each of them is processed   isFilesReady = false    const files = issue.srcElement.files;    const filePromises = Object.entries(files).map(item => {     render new Promise((resolve, turn down) => {       const [alphabetize, file] = item       const reader = new FileReader();       reader.readAsBinaryString(file);        reader.onload = office(outcome) {         // handle reader success          resolve()       };        reader.onerror = function() {         console.log("couldn't read the file");         turn down()       };     })   })    Promise.all(filePromises)     .then(() => {       // if each file candy successfuly and then set our country to true       isFilesReady = truthful     })     .catch((error) => {       panel.log(error)       console.log('something wrong happened')     }) })                  

Now we can access FileReader information using effect.target.result simply we demand to transform it to Base64 cord, let's practice that:

          fileInput.addEventListener('change', async (event) => {   // clean up earliest files   myFiles = {}   // set state of files to fake until each of them is processed   isFilesReady = false    const files = effect.srcElement.files;    const filePromises = Object.entries(files).map(detail => {     render new Promise((resolve, refuse) => {       const [index, file] = item       const reader = new FileReader();       reader.readAsBinaryString(file);        reader.onload = function(event) {         // Convert file to Base64 cord 		// btoa is built int javascript function for base64 encoding         myFiles['picture'] = btoa(event.target.result)          resolve()       };       reader.onerror = function() {         console.log("tin can't read the file");         reject()       };     })   })    Promise.all(filePromises)     .then(() => {       console.log('ready to submit')       isFilesReady = true     })     .catch((fault) => {       panel.log(mistake)       console.log('something wrong happened')     }) })                  

So at present we have converted our file to Base64 string and pushed it within the myFiles object. every fourth dimension our input get changes, myFiles is going to erase all the data it holds and volition procedure everything again.

Converting files to Information URI

We have converted our files to Base64 string just that's not plenty to upload files, we need to convert information technology to Information URI, information technology should wait like this;

          data:prototype/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD/2wCEAAoHCBUWFRgVFRYZGRgZHBgYGBwYGhgYGBoYGBgaGhoZGBgcIS4lHB4rIRgYJjgmKy8xNTU1GiQ7QDs0Py40NTEBDAwMEA8QHBISGjQh...3000 more characters        

The format is;

          data:[<mime type>][;charset=<charset>][;base64],<encoded data>                  

Fortunately, we tin access the MimeType, and so that's going to exist easy like that:

          // Convert Base64 to data URI // Assign it to your object myFiles['picture'] = `data:${file.type};base64,${btoa(issue.target.consequence)}`                  

And so now it's gear up to upload. But permit's make some tweaks before we go along.

I take named our file input every bit picture for the example, let's make our code dynamic so it tin get the file input proper noun attribute

          // this is to get the input name attribute, in our case it volition yield as "picture" // I'm doing this considering I desire you lot to utilise this code dynamically // then if y'all change the input name, the result also going to effect const inputKey = fileInput.getAttribute('proper name')                  

then change this;

          myFiles[inputKey] = `data:${file.type};base64,${btoa(event.target.result)}`                  

that way if you change your input proper name to resume it will yield as myFiles['resume']

Converting multiple files to base64 at one time

Let'due south comprehend our code and so it tin support multiple file input;

          <input type="file" id="pictureInput" multiple/>                  

So in that case, we want to cheque if input has single or multiple files, if it has unmarried file nosotros desire to proper noun it correct according to input name, in our instance it would be picture only if it has more than one file, we are going to name with file lengths such as picture[0], film[1]

here'south the code:

          + // if information technology's multiple upload field then set up the object key as moving-picture show[0], picture[1] + // otherwise just utilize film + const fileKey = `${inputKey}${files.length > i ? `[${index}]` : ''}` + // Convert Base64 to data URI + // Assign it to your object - myFiles[inputKey] = `data:${file.type};base64,${btoa(consequence.target.result)}` + myFiles[fileKey] = `data:${file.type};base64,${btoa(result.target.outcome)}`                  

Handle the grade submit event

Allow'southward comprehend our form submit event, what we want to do in that example is we will check if the files are ready, if they're not nosotros are going to show an warning to user

          const formElement = document.getElementById('formcarryForm')  const handleForm = async (event) => {   event.preventDefault();    if(!isFilesReady){     alarm('files still getting processed')   } }  formElement.addEventListener('submit', handleForm)                  

All of the code nosotros wrote so far should look like this;

          const fileInput = document.getElementById('pictureInput')  // This is for storing the base64 strings let myFiles = {} // if you expect files by default, make this disabled // we will wait until the last file being processed allow isFilesReady = true  fileInput.addEventListener('change', async (upshot) => {   // clean up earliest items   myFiles = {}   // set country of files to false until each of them is processed   isFilesReady = simulated    // this is to get the input name attribute, in our case information technology will yield as "movie"   // I'grand doing this because I desire yous to use this code dynamically   // so if you modify the input name, the result also going to result   const inputKey = fileInput.getAttribute('name')   var files = event.srcElement.files;    const filePromises = Object.entries(files).map(item => {     render new Promise((resolve, reject) => {       const [index, file] = item       const reader = new FileReader();       reader.readAsBinaryString(file);        reader.onload = office(event) {         // if it's multiple upload field and then set the object key as flick[0], movie[1]         // otherwise just use moving-picture show         const fileKey = `${inputKey}${files.length > ane ? `[${index}]` : ''}`         // Convert Base64 to data URI         // Assign it to your object         myFiles[fileKey] = `information:${file.blazon};base64,${btoa(event.target.result)}`          resolve()       };       reader.onerror = function() {         panel.log("can't read the file");         reject()       };     })   })    Promise.all(filePromises)     .and so(() => {       console.log('ready to submit')       isFilesReady = true     })     .catch((mistake) => {       panel.log(error)       panel.log('something wrong happened')     }) })  const formElement = certificate.getElementById('formcarryForm')  const handleForm = async (effect) => {   result.preventDefault();    if(!isFilesReady){     console.log('files however getting processed') 	return   } }  formElement.addEventListener('submit', handleForm)                  

Allow'due south create an object of our course values in the form submit event;

          const formElement = document.getElementById('formcarryForm')  const handleForm = async (event) => {   event.preventDefault();    if(!isFilesReady){     panel.log('files still getting processed')     render   }     const formData = new FormData(formElement)  	// go name and message input from our <form> element   let information = {     'name': formData.become('name'),     'message': formData.go('message')   }  	// iterate over the base64 files nosotros've converted   Object.entries(myFiles).map(item => { 	// destruct the file     const [key, file] = detail 	// suspend it to our data object     information[key] = file   })    panel.log(data) }  formElement.addEventListener('submit', handleForm)                  

Let'south endeavor it out:

What's next?

We've washed all the necessary stuff on the front-end except network request part.

At formcarry we allow our customers to upload files as Base64 (pro feature).

You lot can either use our service to handle your course, or yous tin write a server code to procedure Base64 Data URI.

Luckily for you, I'1000 going to embrace both of them.

1.ane- Uploading Base64 to formcarry

Now we tin can ship our information to formcarry, the important thing in this step is converting our object to JSON and setting the Content Type as application/json.

          const handleForm = async (event) => {   event.preventDefault();    if(!isFilesReady){     console.log('files nevertheless getting processed')     render   }     const formData = new FormData(formElement)    permit data = {     'proper name': formData.get('name'),     'message': formData.get('message')   }    Object.entries(myFiles).map(particular => {     const [key, file] = detail 	// append the file to data object     information[key] = file   })    fetch('https://formcarry.com/south/{Your-Unique-Endpoint}', {     method: 'Mail',     body: JSON.stringify(information),     headers: {       'Content-Type': 'application/json',       Take: 'application/json'     }   })   // convert response to json   .and then(r => r.json())   .so(res => {     panel.log(res);   }); }                  

Changehttps://formcarry.com/s/{Your-Unique-Endpoint} with your unique course ID

1.two- Endeavor it out

Submit your form by filling out all of the fields, then refresh your dashboard

Formcarry will automagically convert your base64 to download-ready file.

2- Uploading Base64 to NodeJS

I'm going to use Limited.js for our example, let's create an express app using limited-generator

          $ npx limited-generator                  

Approximately Base64 files are 33% heavier than the original file, y'all might want to proceed that in mind.

Now, let's allow our server to process big body data by getting into the app.js and alter:

          -app.use(express.json()); -app.employ(express.urlencoded({ extended: simulated })); +app.use(express.json({limit: '50mb'})); +app.use(express.urlencoded({ extended: true, limit: '50mb' }));                  

As well we need to enable CORS to perform request from our front-end app:

          npm i --save cors                  

Enable information technology similar this:

          var limited = require('express'); var ba64 = require('ba64') var cors = require('cors')  var app = express();  app.employ(cors());                  

I'm going to remove all the unnecessary stuff, yous can supplant this with your app.js:

          var createError = require('http-errors'); var express = require('express'); var path = require('path'); var cors = crave('cors')  var app = express();  app.employ(cors());  app.apply(express.json({limit: '50mb'})); app.use(express.urlencoded({ extended: truthful, limit: '50mb' })); app.use(express.static(path.join(__dirname, 'public')));  // take hold of 404 and frontwards to mistake handler app.use(function(req, res, side by side) {   adjacent(createError(404)); });  // mistake handler app.use(function(err, req, res, adjacent) {   // set locals, but providing mistake in development   res.locals.bulletin = err.bulletin;   res.locals.error = req.app.get('env') === 'development' ? err : {};    // render the error page   res.status(err.status || 500);   res.render('error'); });  module.exports = app;                  

2.i- Creating our procedure route

Now nosotros need to create a Limited route to process our form information.

Just kickoff nosotros are going to use a tiny package called ba64 which will help the states to save base64 images to our disk.

The menstruum should exist similar this;

  • Bank check the key is a valid Data URI
  • If it'south valid excerpt the Base64 string from Information URI
  • Extract the mimetype from Data URI
  • Save to the disk

That's where ba64 packet comes in, information technology will automatically extract Base64 string from Data URI, and append the file extension afterward the file proper noun automatically.

          npm i --save ba64                  

Import information technology in our app.js

          var ba64 = crave('ba64')                  

Let's create our route, go to app.js and add together following:

          app.mail('/upload', async (req, res, next) => {   // exclude name and message for the sake of demo   // all other body items will be considered as a file   const { name, message, ...files } = req.body    for(let key in files){     const base64 = files[key]      // cheque if it's correctly formatted Base64 Information URI     if(checkBase64(base64)){       // Write it to our root directory using input key as filename       // eg. picture[1]       ba64.writeImageSync(key, base64)     }   }    res.transport({files}) })  office checkBase64(cord){   const B64_REGEX = /^data:.*;base64,([0-9a-zA-Z+\\/]{iv})*(([0-9a-zA-Z+\\/]{two}==)|([0-9a-zA-Z+\\/]{3}=))?$/i     render B64_REGEX.test(string) }                  

Last code should wait like:

          var createError = require('http-errors'); var express = crave('express'); var path = crave('path'); var ba64 = crave('ba64') var cors = require('cors')  var app = express();  app.use(cors());  // view engine setup app.use(limited.json({limit: '50mb'})); app.use(express.urlencoded({ extended: truthful, limit: '50mb' })); app.use(limited.static(path.join(__dirname, 'public')));   app.post('/upload', async (req, res, side by side) => {   // exclude name and message for the sake of demo   // all other body items volition be considered every bit a file   const { name, message, ...files } = req.body    for(allow key in files){     const base64 = files[central]      // check if it's correctly formatted Base64 Information URI     if(checkBase64(base64)){       // Write it to our root directory using input central as filename       // eg. picture[1]       ba64.writeImageSync(central, base64)     }   }    res.send({files}) })  function checkBase64(string){   const B64_REGEX = /^data:.*;base64,([0-9a-zA-Z+\/]{4})*(([0-9a-zA-Z+\/]{ii}==)|([0-9a-zA-Z+\/]{3}=))?$/i     return B64_REGEX.examination(cord) }  // grab 404 and forward to error handler app.use(function(req, res, side by side) {   adjacent(createError(404)); });  // error handler app.use(function(err, req, res, next) {   // fix locals, merely providing error in development   res.locals.bulletin = err.message;   res.locals.fault = req.app.get('env') === 'development' ? err : {};    // return the mistake page   res.status(err.condition || 500);   res.return('fault'); });  module.exports = app;                  

Now run the app using:

          $ npm start                  

ii.2 - Configure Front-end

Let's become dorsum to our forepart-cease code and point our form to the dorsum-end our server runs at http://localhost:3000 and our route is localhost:3000/upload

          const handleForm = async (result) => {   outcome.preventDefault();    if(!isFilesReady){     console.log('files however getting candy')     return   }     const formData = new FormData(formElement)    allow data = {     'name': formData.get('proper name'),     'message': formData.go('bulletin')   }    Object.entries(myFiles).map(item => {     const [key, file] = item 	// suspend the file to data object     data[key] = file   })    fetch('http://localhost:3000/upload', {     method: 'Mail service',     body: JSON.stringify(data),     headers: {       'Content-Blazon': 'application/json',       Take: 'application/json'     }   })   // convert response to json   .then(r => r.json())   .and so(res => {     console.log(res);   }); }                  

Let'south endeavor it:

It works!

Conclusion

Cheers for following the blog post to the end, base64 is a tricky issue that'south why I wanted to gear up an end-to-end fully functional tutorial.

I hope information technology's beneficial for you, if you lot have any questions but get out a comment and I'll try my best.

If you desire to support us, just take a look at our service formcarry for a hassle free form handling.

  • Guides

Source: https://formcarry.com/blog/how-to-upload-files-as-base64/

Posted by: boyddering74.blogspot.com

0 Response to "How To Upload File In Google Form"

Post a Comment

Iklan Atas Artikel

Iklan Tengah Artikel 1

Iklan Tengah Artikel 2

Iklan Bawah Artikel