0

I'm creating a web app in Google Apps Script that allows businesses to upload PDF-format 'supporting documentation' for their commercial insurance audits. The program serves the upload page via a GET request, and then the page POSTs the file(s) and identifying information to the same URL. Users will not have a Google account.

It worked fine when loading the encoded file contents into a hidden form on the page, and then having the form POST its contents, per these instructions from Tanaike. The drawback to this method is adding a potentially huge amount of data to single form fields: a 60 MB file slowed Chrome to a crawl and eventually crashed it. The files are often going to be scanned documents, so large file sizes are a possibility.

To avoid this problem, I tried using the XMLHttpRequest instead, but immediately ran into problems with CORS:

Access to XMLHttpRequest at 'https://script.google.com/a/[REDACTED]/exec' from origin 'https://[REDACTED]script.googleusercontent.com' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.

The recommended solution seems to be to make sure that the POST request is a 'simple request' that doesn't trigger a CORS preflight check.

Despite following the recommendations for a simple request, I'm still getting a CORS failure. I've pared the program down to this:

Server-side:

function doPost(e) {
  Logger.log(e.postData.contents);
  return ContentService.createTextOutput();
}

Client side (within a function called as the user form onsubmit handler):

    // postURL is the deployed URL of the web app, ending in /exec.
    const xhr = new XMLHttpRequest();
    xhr.open('POST', postURL);
    xhr.setRequestHeader('Content-Type', 'text/plain');
    xhr.send(JSON.stringify({'message': 'Hello world!'}));

I have tried using the web app deployed both for 'Only Myself' and for 'Anyone', with no change. It is set to run as me, which it will have to do in order to do what it needs to do with the uploaded files.

It looks like Tanaike's resumable upload example program manages to use XMLHttpRequest and PUT by getting an OAuth token from the server-side script. I'm not sure yet if that will work for a semi-anonymous upload like I'm trying to do.

Am I trying to do something inherently impossible due to Apps Script limitations, or have I missed something?

maboyce
  • 23
  • 4
  • Your ultimate goal is to prevent user upload huge file, right? Why don't you simply check the `blob.size` before execution of upload with `doPost`? – idfurw Aug 21 '21 at 08:38
  • There's a Google service limit at 50 MB that I check for, but the issue is that the browser is bogging down before that point using my current method of POSTing using a hidden form. – maboyce Aug 21 '21 at 14:24
  • I am suggesting this method, am I misunderstanding something? [Get file size before uploading](https://stackoverflow.com/a/7497439/16125139) – idfurw Aug 21 '21 at 15:21
  • Yes, I know how to get the file size; it's the problem with CORS that's got me stumped. – maboyce Aug 22 '21 at 00:23

0 Answers0