使用嵌入式谷歌表单绕过 CORS

Posted

技术标签:

【中文标题】使用嵌入式谷歌表单绕过 CORS【英文标题】:Getting around CORS with embedded google forms 【发布时间】:2017-10-16 04:08:59 【问题描述】:

我正在尝试通过嵌入式表单向谷歌发送表单数据。

我发现这个post 似乎回答了我的问题,但我遇到了 CORS 错误。有没有办法解决这个问题?

其他帖子似乎说 CORS 不是问题,但我遇到了错误。

这是我的代码:

-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>

【问题讨论】:

请使用***.com/posts/44012261/edit 编辑/更新您的问题,并添加您在浏览器开发工具控制台中看到的确切错误消息。 XMLHttpRequest cannot load https://docs.google.com/forms/d/e/xxxxxxxxxxxxxxxx/formResponse. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'https://xxx.mydomain.com' is therefore not allowed access. 【参考方案1】:

“请求的资源上不存在 'Access-Control-Allow-Origin' 标头” 消息表明来自 https://docs.google.com/forms/d/e/xxxx/formResponse URL 的响应当前不包含 Access-Control-Allow-Origin 响应标头,因此浏览器将不允许您的前端 JavaScript 代码访问响应。

鉴于此,我想从您的前端代码中您无法判断 POST 请求是否成功。但除非出现任何其他问题,否则请求似乎总是会成功。如果请求根本没有到达服务器(由于某些网络错误),那么您将遇到从前端代码中可以观察到的不同故障条件,因此您可以实际捕获它。

所以我猜你知道请求已成功到达服务器的方式只是你没有收到任何其他可以从前端代码中观察到的故障。

【讨论】:

这是正确的。我查看了另一篇文章的工作代码,出现了相同的 CORS 错误,但请求成功。由于某种原因,我的请求没有成功,但与此无关。谢谢! 看来(除了 JS 控制台中的 CORS 响应错误之外)Google 表单现在阻止 POST 提交通过。至少在我的测试中。如果我删除通过 Ajax 处理表单 POST 的 javascript,并通过浏览器通过操作属性提交表单,我现在在 Google Forms UI There was a problem submitting your response 中收到错误。【参考方案2】:

我发现,将隐藏的 iframe 作为其目标的 POST 表单实际上更容易,并在提交响应时捕获 iframe 重新加载。

例如,如果这是您的表单:

<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>

然后在同一页面上包含一个 iframe,其 id 和名称与您在表单中作为目标放置的相同:

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

提交表单后,它应该使用“您的回复已被记录”重新加载该 iframe。来自谷歌的页面。我们可以使用 JavaScript 捕获重新加载,因此在您的表单和 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>

您无法检查响应是否正确提交,因为您无法检查跨域 iframe 的内容(这将是一个巨大的安全风险),因此只需假设如果此 iframe 重新加载,响应没问题。

您可以使用以下 CSS 隐藏 iframe:

visibility: hidden
height: 1px;

如果你问我会更干净,没有控制台错误或失败的请求。

【讨论】:

+1。请注意,在 android 上,如果 iframe 不可见,它将不起作用,因此您必须解决这个问题,例如绝对定位在看不见的地方

以上是关于使用嵌入式谷歌表单绕过 CORS的主要内容,如果未能解决你的问题,请参考以下文章

添加嵌入式谷歌地图时console.log中的警告

嵌入式谷歌地图无法在 WebView 中获取当前位置

嵌入式谷歌地图上的双指缩放缩放整个页面

如何从访问者的当前位置获取方向到我在嵌入式谷歌地图中的位置

尽管准确的纬度/经度,但是〜100米的谷歌地图嵌入不正确

在本地 HTML 文件中嵌入 Google 趋势图时遇到问题