How to capture uploaded file in post request to Google Apps Script? - javascript

I am trying to build a script to save data (text + image + pdf) from an HTML form (NOT Google Form).
I have the following function to upload a file:
function upload(x) {
var destination_id = 'folder_id'
var destination = DriveApp.getFolderById(destination_id)
var contentType = 'image/png'
var img = x.getAs(contentType)
destination.createFile(img)
}
Inside my doPost function I am calling the above upload function like this:
upload(e.parameter.img)
I have an input of type file with a name and id of img. I also have the following event listener to prepare the body of the POST request:
form.addEventListener('submit', e => {
e.preventDefault()
let fd = new FormData(form)
fetch(scriptURL, { method: 'POST', body: fd})
.then(response => console.log('Success!', response))
.catch(error => console.error('Error!', error.message))
})
When I submit my form, my text gets saved, but the file is not uploaded. I do not see any errors in the console either. What am I doing wrong? Is there an easier alternative to uploading form data to Google Drive?

type=file don't seem to be currently supported. You can workaround this using FileReader api on the client side to convert file data to a base64 encoded websafe string and send the data as string or a byte array.
Related answer

Related

Next JS data fetching with file body

I am trying to send a POST request to upload a file to my IPFS server. However I am unsure how can I upload a file into the body of the request. I have tried looking at the examples from Fetch API, but their example shows files uploaded from a form. While in my case, the files are already within my directory.
Update:
I have revised my code for sending a POST request to my IPFS server based on the documentation on Fetch API and I am now able to successfully send a request. However I am still stuck on how can I get the "fileInput" variable to reference a file from my directory. The current example only works if I have a html form.
I have tried nodejs fs library but I ran into issues where some of the functions are not available. It appears that using fs may pose certain security concerns from what I read. Would appreciate if I can have some advice on this.
var formdata = new FormData();
const fileInput = document.querySelector('input[type="file"]');
formdata.append(
"file",
fileInput.files[0],
`../../ipfs_files/${item._id}.png`
);
var requestOptions = {
method: "POST",
body: formdata,
redirect: "follow",
};
fetch("http://localhost:5001/api/v0/add", requestOptions)
.then((response) => response.text())
.then((result) => console.log(result))
.catch((error) => console.log("error", error));
you can also send data as base64 string and store it into the database then while accessing convert back to the original format.

JavaScript - Axios POST request empty form data (request payload)

I have a Vue.js app which uses axios to interact with a Laravel API. I'm trying to make a POST request with an image file in it to upload in the backend.
The issue I'm having is that axios makes the POST request with empty payload.
I've tried sending it both as a plain JS object and with FormData. In both cases the request payload is empty. I've looked on the internet for hours but I was unable to find anything while trying to tackle the issue in the past few days...
This is how I make the request:
let fd = new FormData();
fd.append('file', this.file);
console.log(...fd) //shows the file is there with its data
axios
.post("/api/images", fd)
.then(response => {
//Handle success
})
.catch(errors => {
//Catch errors
});
This is how I get the file from the form:
let selectedImage = this.$refs.fileInput.files[0];
const reader = new FileReader();
reader.addEventListener('load', (event) => {
this.file = event.target.result;
});
reader.readAsDataURL(selectedImage);
I've tried experimenting with the request headers and at the moment they are as follows:
"Accept" : "application/json",
"Content-Type": "multipart/form-data; charset=utf-8; boundary=" + Math.random().toString().substr(2),
"Authorization": "Bearer " + this.user.api_token,
"X-CSRF-TOKEN": document.querySelector('meta[name="csrf-token"]').content
The responses from Laravel are always that the file is required (as expected when it's indeed missing).
I did try encoding the file in Base64 but I have trouble validating that it's an image in the backend.
I found this similar question but it wasn't of any help: FormData sends empty data using axios
I want to send a file + JSON data but I'm ok with just making the file upload work. So... How do I send a file from Vue.js app to Laravel API using Axios? What am I doing wrong?

Why is my Giphy API's POST request returning status 400?

I'm trying to upload a gif from the webcam feed to Giphy through their API and it returns status 400 - "Please supply a file upload or a 'source_image_url'". My function does this:
upload = new FormData();
upload.append("file", gif, "usergif.gif");
console.log(upload.get("file"));
fetch("https://upload.giphy.com/v1/gifs?file=" upload + "&api_key=" + apiKey, { method: "POST" })
.then(response => {
console.log(response.status);
return response.json;
}
)
The gif variable inside upload.append() has a value of recorder.getBlob() (I'm using the RecorderRTC API), I also tried to use as a source upload.file and even upload.get("file"), also used URL.createObjectUrl(gif) and changed file= for source_image_url= in the fetch request, even tried to send the gif variable without the use of FormData() but nothing worked.
Do you have a clue?
For those interested, the solution was that when using the POST method, you gotta specify a body header with the file to be uploaded

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)
*/

Can't correctly use fetch to PUT file on S3

Using a pre-signed URL I am trying to PUT an object (an image) in my AWS S3 bucket using JavaScript's fetch.
Below is the snippet of code I'm using, triggered by a change event on a file upload input.
// The event here is from a change
// trigger on the file input
const target = event.target
const file = target.files[0]
const reader = new FileReader()
reader.onload = (event) => {
fetch(PRESIGNED_S3_URL, {
method: 'put',
body: event.target.result,
headers: new Headers({
'Content-Type': file.type
}),
}).then((response) => {
response.json().then((data) => {
// Success
})
})
}
// Read the selected file
reader.readAsText(file)
This does indeed upload the file, setting its name and filetype correctly, but when I try to view the file it is corrupt.
I am stuck on what I am doing incorrectly to read and upload the file contents. Any help is appreciated!
To upload an image, you need to set content handling to CONVERT_TO_BINARY.

Categories

Resources