Home > OS >  Getting around CORS with embedded google forms
Getting around CORS with embedded google forms

Time:08-31

I'm trying to send form data to google via an embedded form.

I found this post that seems to answer my question but I'm getting CORS errors. Is there a way to solve this?

Other posts seem to say that CORS isn't an issue but I'm getting the errors.

Here is my code:

-JS-

function ajax_post() {
  var field1 = $('#email').val();

  $.ajax({
      url: "https://docs.google.com/forms/d/e/xxxxxxxxxxxxxxxxxxxxxx/formResponse",
      data: {"entry.xxxxxxxxxx": field1},
      type: "POST",
      dataType: "xml",
      statusCode: {
          0: function() {
          //Success message
          },
          200: function() {
          //Success Message
          }
      }
  });
}

-HTML-

<form id="emailForm" target="_self" onsubmit="" action="javascript: ajax_post()">
    <input id="email" type="text" autocomplete="off" tabindex="0" name="entry.xxxxxxxxxx" required>
    <button id="send" type="submit">Submit</button>
</form>

CodePudding user response:

The “No 'Access-Control-Allow-Origin' header is present on the requested resource” message indicates that responses from https://docs.google.com/forms/d/e/xxxx/formResponse URLs currently don’t include the Access-Control-Allow-Origin response header, so browsers won’t allow your frontend JavaScript code to access the response.

Given that, from your frontend code there’s no way you can tell if the POST request succeeds or not. But barring any other problems, it seems like the request will always succeed. If the request doesn’t reach the server at all (due to some network error) then you’ll hit a different failure condition that is observable from your frontend code so you can actually catch it.

So the way you know the request has successfully reached the server is just that you don’t get any other failure that’s observable from your frontend code.

CodePudding user response:

I've found that it's actually easier to just POST the form with a hidden iframe as its target, and capture that iframe reload when the response is submitted.

For example, if this is your form:

<form id="my-form" target="my-response-iframe" action="https://docs.google.com/forms/u/1/d/e/<YOUR-ID>/formResponse" method="post">
  <input type="text" name="entry.12345678" value="" required>
  <input type="submit">
</form>

Then include an iframe on the same page, with the same id AND name you put as target in the form:

<iframe id="my-response-iframe" name="my-response-iframe"></iframe>

When the form is submitted, it should reload that iframe with the "Your response has been recorded." page from Google. We can catch that reload with JavaScript, so include this after your form and iframe:

<script type="text/javascript">
   // set the target on the form to point to a hidden iframe
   // some browsers need the target set via JavaScript, no idea why...
   document.getElementById('my-form').target = 'my-response-iframe';
   // detect when the iframe reloads
   var iframe = document.getElementById('my-response-iframe');
   if (iframe) {
     iframe.onload = function () {
       // now you can do stuff, such as displaying a message or redirecting to a new page.
     }
   }
</script>

You can't check whether the response was submitted correctly because you can't inspect the contents of a cross-origin iframe (that'd be a huge security risk), so just assume that if this iframe reloads, the response was ok.

You can hide the iframe with the following CSS:

visibility: hidden
height: 1px;

Much cleaner if you ask me, with no console errors or failed requests.

  • Related