繁体   English   中英

无法使用 JS Fetch 向 Google Web 应用程序发出跨域资源共享 (CORS) 请求

[英]Unable to Make Cross Origin Resource Sharing (CORS) request to Google Web App Using JS Fetch

我制作了一个谷歌 web 应用程序,它接收发布请求并将数据发布到谷歌表格。 web 应用程序的代码如下:

var sheetName = 'Sheet'

var scriptProp = PropertiesService.getScriptProperties()

function setup () {
  var doc = SpreadsheetApp.getActiveSpreadsheet()
  scriptProp.setProperty('key', doc.getId())
}

function doPost (e) {
  
  var lock = LockService.getScriptLock()

  lock.waitLock(10000)

  try {
    
    var doc = SpreadsheetApp.openById(scriptProp.getProperty('key'))

    var sheet = doc.getSheetByName(sheetName)

    var headers = sheet.getRange(1, 1, 1, sheet.getLastColumn()).getValues()[0]
    // Gets the last row and then adds one
    var nextRow = sheet.getLastRow() + 1

    var newRow = headers.map(function(header) {
      return header === 'timestamp' ? new Date() : e.parameter[header]
    })
    
    sheet.getRange(nextRow, 1, 1, newRow.length).setValues([newRow])

    
    return ContentService
    .createTextOutput(JSON.stringify({ 'result': 'success', 'row': nextRow, 'rows': newRow }))
      .setMimeType(ContentService.MimeType.JSON)
  }

  catch (e) {
    return ContentService
      .createTextOutput(JSON.stringify({ 'result': 'error', 'error': e }))
      .setMimeType(ContentService.MimeType.JSON)
  }

  finally {
    
    lock.releaseLock()
  }
}

查看工作表的链接是: https://docs.google.com/spreadsheets/d/1w8M_Jlo4YKhkbTjlXbWybiTONjWylXSFFThNPo5e9CM/edit#gid=0

我想使用我的 static web 页面上的按钮将数据提交到工作表,所以我写了一些基本的 JS 使用 fetch 来提交发布请求。 I kept getting blocked by the cors preflight requirement since my page is static (hosted by Github Pages) and does not have a server to respond to the cors preflight. 所以我在任何地方添加了 heroku CORS ,但我仍然无法将任何内容发布到工作表上。 我一直在通过访问 girling.info 进行测试,我的 static 页面(仍在进行中)打开调试器控制台并运行代码。 JS获取代码:

fetch('https://cors-anywhere.herokuapp.com/https://script.google.com/macros/s/AKfycbyjt4Yg22ERgK3FS11UIPmGE1_sBLEt-kh0vRF37rAI3ujIu5DC/exec',
       {
       method: 'POST',
       mode: 'cors',
       headers: {'Origin': 'true', 'X-Requested-With': 'true', 'User-Agent': 'python-requests/2.23.0', 'Accept-Encoding': 'gzip, deflate', 'Accept': '*/*', 'Connection': 'keep-alive'}, 
       body: {'Email': 'lala@la.com', 'Timestamp': 24},
       }).then(response => console.log(response));

我收到了 code=200 的回复,但实际上没有数据发布到工作表。

我已经验证的事情:

  1. web 应用程序通过使用命令行提交带有 python 请求的发布请求来工作
  2. 我正文中的文本与工作表中的列完全匹配

我可以使用一些帮助

web 应用程序已发布,任何人都可以访问它。 这是设置的屏幕抓取:屏幕抓取

我将 'cache': 'no-cache', 'redirect': 'follow' 添加到我的标题中,但仍然得到相同的结果。 这是控制台的屏幕截图。 控制台日志

By looking at the execution history for the google web api, I found that when I submit a post request using JS CORS, the web app executes but puts null in the data spots.

问题是由于没有将 CORS 主体格式化为 JS FormData object 或可以通过以下方式访问的内容

var newRow = headers.map(function(header) {
      return header === 'timestamp' ? new Date() : e.parameter[header]
    }) 

当我直接在 CORS 请求正文中提交字典时,我认为 e.parameter[header] 没有找到任何东西,所以它返回 null。 这解释了为什么谷歌应用程序正在运行但输入 null。 我的确认测试是使用此表格在我的计算机上制作 html 页面

<form name="submit-to-google-sheet" method="post" target=_self>
  <label for="Timestamp">Timestamp:</label> <br>
  <input name="Timestamp" type="text"  value="Automatically updated on submit" size="30" > <br>
  <label for="0001"> How many times in the last 5 years have you seen this question in an interview:</label> <br>
  <input name="0001" type="text"  value=0 size="30" required> <br>

和这个脚本

<script>
  const scriptURL = 'https://script.google.com/macros/s/AKfycbyjt4Yg22ERgK3FS11UIPmGE1_sBLEt-kh0vRF37rAI3ujIu5DC/exec'
  // html form
  let form = document.forms['submit-to-google-sheet']

  form.addEventListener('submit', e => {
    e.preventDefault()
    // make formdata object
    let form1 = new FormData(form)
    // setting timestamp
    form1.set('Timestamp', new Date())
    fetch(scriptURL, { method: 'POST', body: form1})
      .then(response => console.log('Success!'))
      .catch(error => console.error('Error!'))
    reset_form = function (form_name, input_name) {
      document.getElementsByName(input_name)[0].value = 'Thank your for your submission!!'
    }
    reset_form('submit-to-google-sheets', 'Timestamp')
    reset_form('submit-to-google-sheets', '0001')
  })
</script>

感谢所有的帮助!

我必须说,处理 doGet 和 doPost 是一场斗争。 我看到您在客户的发布请求中缺少密钥。 尝试添加缓存:'no-cache',重定向:'follow'。 交叉手指让你的代码工作

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM