How to upload a file via POST (doPost) to a Google Script's Web App?
My question is exactly as this one: Upload a file to a Google Web Apps with doPost
How to upload a file directly to a Google Script's Web App from another domain? I answered a workaround in that question to convert the file in a base64 string but the question remains. Is it possible to upload a file to Google Scripts or only strings?
Solution 1:
Files cannot be uploaded directly by "doPost()" of GAS from HTML form on local PC. Because "multipart/form-data" may be not able to be used for "doPost()". So converting Base64 leads to the solution as you say.
There are 2 ways for uploading files by "doPost()".
1. Upload a file from HTML form on GAS project
This uploads a file using GAS and HTML in GAS project. In this case, the file doesn't convert to Base64 by the script. (It may convert as the internal process.)
2. Upload a file from HTML form on local PC
This uploads a file from HTML form on local PC. GAS controls "doPost()". In this case, the file is encoded to Base64 and upload as text data, and then decoded to the file using GAS.
1. Upload a file from HTML form on GAS project
Rule :
Following sample script and HTML have to be made into a project of Google Apps Script.
Deploy the GAS project as a web application. https://developers.google.com/apps-script/guides/web And retrieve URL.
After updated the script, it has to be updated as a new version.
Form.html :
<html>
<body>
<form>
<input type="file" name="upFile">
<input type="button" value="ok" onclick="google.script.run.upload(this.parentNode)">
</form>
</body>
</html>
Script :
function doGet() {
return HtmlService.createHtmlOutputFromFile('Form.html');
}
function upload(e) {
DriveApp.createFile(e.upFile);
}
2. Upload a file from HTML form on local PC
The rule is almost the same to above one. The script is placed on GAS project. But HTML form is placed on local PC.
Script :
function doGet(e) {
return message("Error: no parameters");
}
function doPost(e) {
if (!e.parameters.filename || !e.parameters.file) {
return message("Error: Bad parameters");
} else {
var data = Utilities.base64Decode(e.parameters.file, Utilities.Charset.UTF_8);
var blob = Utilities.newBlob(data, MimeType.PNG, e.parameters.filename);
DriveApp.createFile(blob);
return message("completed");
}
}
function message(msg) {
return ContentService.createTextOutput(JSON.stringify({result: msg})).setMimeType(ContentService.MimeType.JSON);
}
HTML :
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<script src="http://code.jquery.com/jquery-latest.js" type="text/javascript"></script>
</head>
<body>
<input type="file" id="file">
<script type="text/javascript">
$(function(){
var url = 'https://script.google.com/macros/s/[Project ID]/exec';
var params = {
filename: 'samplefile',
imageformat: 'PNG'
};
$('#file').on("change", function() {
var file = this.files[0];
var fr = new FileReader();
fr.onload = function(e) {
params.file = e.target.result.replace(/^.*,/, '');
postJump();
}
fr.readAsDataURL(file);
});
function postJump(){
var html = '<form method="post" action="'+url+'" id="postjump" style="display: none;">';
Object.keys(params).forEach(function (key) {
html += '<input type="hidden" name="'+key+'" value="'+params[key]+'" >';
});
html += '</form>';
$("body").append(html);
$('#postjump').submit();
$('#postjump').remove();
}
});
</script>
</body>
</html>
This sample script supposes to upload a PNG file as a test. If you want to upload other files, please change mime type. https://developers.google.com/apps-script/reference/base/mime-type
For HTML sample, the file is uploaded when the file is selected.
If this will be helpful for you, I'm glad.