如何在Google Apps Script中实现CORS?跨域请求问题求助
Google Apps Script Web App 解决CORS跨域问题
问题场景
在通过Chrome扩展向Google Apps Script(GAS)Web App发送GET请求获取Google Sheet数据时,触发CORS错误:
hello.html:1 从源'chrome-extension://{extensionid}'访问"/apps script web applink"(重定向自"/apps script web applink")时被CORS策略阻止:预检请求的响应未通过访问控制检查:请求的资源上不存在'Access-Control-Allow-Origin'标头。如果不需要透明响应,可将请求模式设为'no-cors'以禁用CORS获取资源。
前端请求代码
url = "google apps script web app link" fetch(url, { method: "GET", headers: { "Content-Type": "application/json", }, mode: "cors", })
原GAS代码(未处理CORS)
function doGet() { var sheetId = "sheetId"; var sheetName = "Sheet1"; var sheet = SpreadsheetApp.openById(sheetId).getSheetByName(sheetName); var data = sheet.getDataRange().getValues(); var headers = data[0]; var jsonData = []; for (var i = 1; i < data.length; i++) { var row = data[i]; var rowData = {}; for (var j = 0; j < headers.length; j++) { rowData[headers[j]] = row[j]; } jsonData.push(rowData); } var jsonOutput = JSON.stringify(jsonData); var response = ContentService.createTextOutput(jsonOutput) .setMimeType(ContentService.MimeType.JSON); return response; }
问题原因
- 原代码未添加
Access-Control-Allow-Origin等关键CORS响应头,浏览器无法确认跨域请求权限 - Chrome扩展发起的跨域请求会触发OPTIONS预检请求,原GAS代码未实现
doOptions函数处理该请求,导致预检失败
修复后的GAS代码
// 处理GET请求 function doGet() { var sheetId = "sheetId"; var sheetName = "Sheet1"; var sheet = SpreadsheetApp.openById(sheetId).getSheetByName(sheetName); var data = sheet.getDataRange().getValues(); var headers = data[0]; var jsonData = []; for (var i = 1; i < data.length; i++) { var row = data[i]; var rowData = {}; for (var j = 0; j < headers.length; j++) { rowData[headers[j]] = row[j]; } jsonData.push(rowData); } var jsonOutput = JSON.stringify(jsonData); // 添加CORS响应头 return ContentService.createTextOutput(jsonOutput) .setMimeType(ContentService.MimeType.JSON) .setHeaders({ "Access-Control-Allow-Origin": "*", // 允许所有来源,若需限制可替换为具体域名/扩展ID "Access-Control-Allow-Methods": "GET, POST, OPTIONS", "Access-Control-Allow-Headers": "Content-Type" }); } // 处理OPTIONS预检请求 function doOptions() { return ContentService.createTextOutput("") .setMimeType(ContentService.MimeType.TEXT) .setHeaders({ "Access-Control-Allow-Origin": "*", "Access-Control-Allow-Methods": "GET, POST, OPTIONS", "Access-Control-Allow-Headers": "Content-Type" }); }
额外注意事项
- Web App部署设置:重新部署GAS Web App时,需设置“谁可以访问此应用”为任何人,甚至匿名(若允许公开访问);若需授权访问,需额外处理OAuth2验证,但会增加跨域复杂度
- 限制来源:若不想允许所有来源,可将
Access-Control-Allow-Origin的值替换为你的Chrome扩展ID(格式:chrome-extension://{你的扩展ID}),提升安全性 - 请求头简化:如果前端GET请求不需要
Content-Type: application/json,可以移除该头,避免触发预检请求(GET请求默认无需此头,仅POST发送JSON时需要)
内容的提问来源于stack exchange,提问作者Darshan Vaghasiya
相关产品推荐
相关产品推荐

