React+Vite项目向Google Sheets传数据时出现CORS错误如何调试?
调试Google Sheets + React的CORS请求错误
问题背景
尝试用Google Sheets存储React应用数据,前端组件代码:
const data = { ...userData, ...selectedOptions.reduce((acc, option, index) => { const alphabetOption = numericToAlphabets[option]; acc[`question${index + 1}`] = alphabetOption; return acc; }, {}), }; try { await axios.post(googleScriptUrl, data); } catch (error) { console.log(error); }
对应的Google Apps Script代码:
const sheet = SpreadsheetApp.openByUrl("google-sheet-url").getSheetByName("Sheet1"); const data = e.parameter; sheet.appendRow([ data.name, data.email, data.education, data.gender, data.dateOfBirth, ...Object.keys(data).filter(key => key.startsWith("question")).map(key => data[key]), ]); // Set CORS headers const responseHeaders = { 'Content-Type': 'application/json', 'Access-Control-Allow-Origin': '*', // Allow requests from any origin (replace with specific origin if needed) 'Access-Control-Allow-Methods': 'POST', 'Access-Control-Allow-Headers': 'Content-Type' }; const response = ContentService.createTextOutput("Your message was successfully sent to the Google Sheet database!"); response.setMimeType('application/json'); response.setHeaders(responseHeaders); return response; }
出现的错误:
Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at "google-sheet-url" (Reason: CORS request did not succeed). Status code: (null). Object { stack: "AxiosError@http://localhost:3000/node_modules/.vite/deps/axios.js?v=481c8f0f:377:18\nhandleError@http://localhost:3000/node_modules/.vite/deps/axios.js?v=481c8f0f:1450:14\n", message: "Network Error", name: "AxiosError", code: "ERR_NETWORK", config: {…}, request: XMLHttpRequest }
调试步骤
1. 修正请求URL(最常见错误)
你当前请求的是Google Sheet的直接URL,但前端应调用Google Apps Script部署后的Web应用URL。部署步骤:
- 打开Apps Script编辑器,点击右上角「部署」→「新部署」
- 类型选择「Web应用」
- 执行权限设为「任何人,甚至匿名」(测试阶段使用,后续可按需调整)
- 点击部署,复制生成的类似
https://script.google.com/macros/s/[部署ID]/exec的URL,替换前端的googleScriptUrl
2. 处理OPTIONS预检请求
浏览器发送POST前会先发送OPTIONS预检请求,原脚本未处理该请求导致CORS失败。修改Apps Script代码:
function doPost(e) { // 处理OPTIONS预检请求 if (e.method === 'OPTIONS') { const response = ContentService.createTextOutput(''); response.setHeaders({ 'Access-Control-Allow-Origin': '*', 'Access-Control-Allow-Methods': 'POST', 'Access-Control-Allow-Headers': 'Content-Type' }); return response; } // 数据存储逻辑 const sheet = SpreadsheetApp.openByUrl("你的Google Sheet URL").getSheetByName("Sheet1"); // 解析JSON格式的请求数据(Axios默认发送JSON) const data = JSON.parse(e.postData.contents); sheet.appendRow([ data.name, data.email, data.education, data.gender, data.dateOfBirth, ...Object.keys(data).filter(key => key.startsWith("question")).map(key => data[key]), ]); // 响应POST请求 const responseHeaders = { 'Content-Type': 'application/json', 'Access-Control-Allow-Origin': '*', 'Access-Control-Allow-Methods': 'POST', 'Access-Control-Allow-Headers': 'Content-Type' }; const response = ContentService.createTextOutput(JSON.stringify({message: "数据已成功保存到Google Sheets"})); response.setMimeType(ContentService.MimeType.JSON); response.setHeaders(responseHeaders); return response; }
3. 匹配请求数据格式
Axios默认发送application/json格式数据,原脚本用e.parameter只能解析x-www-form-urlencoded格式,所以改用JSON.parse(e.postData.contents)读取JSON数据。前端可明确设置请求头:
await axios.post(googleScriptUrl, data, { headers: { 'Content-Type': 'application/json' } });
4. 验证Apps Script可访问性
- 直接在浏览器中访问部署后的Web应用URL,确认URL有效、权限正常(doPost接口GET请求会报错,但能排除URL无效问题)
- 用Postman发送POST请求测试,排除前端环境干扰
5. 查看浏览器网络详情
打开Chrome开发者工具「Network」标签:
- 检查「Request URL」是否为正确的Web应用URL
- 查看「Response」标签获取详细错误信息
- 若OPTIONS请求失败,重点检查预检请求的响应头是否正确
内容的提问来源于stack exchange,提问作者Rajveer Kania
相关产品推荐
相关产品推荐

