如何让Google Sheets查看权限用户在指定部署的Web App中增改记录?
问题分析
你遇到的错误根源是:Web App以「访问Web App的用户」身份执行时,拥有Sheets查看权限的用户调用修改表格的服务端函数时,会因自身没有编辑权限触发权限错误,客户端捕获后抛出你看到的JS异常。而拥有编辑权限的用户能正常操作,是因为他们的身份允许修改表格。
解决方案
要在维持现有部署设置(执行身份:访问用户;访问权限:任何Google账户用户)的前提下实现需求,需要让修改操作以拥有编辑权限的身份(即你,Web App部署者)执行,同时保留原Web App的用户身份验证逻辑。以下是具体实现步骤:
1. 创建代理Web App处理修改操作
首先创建一个独立的代理脚本,负责实际的表格修改操作,部署时使用你的身份执行:
// 代理脚本的Code.gs function addRecord(data) { // 替换为你的表格ID和工作表名称 const spreadsheetId = 'YOUR_SPREADSHEET_ID'; const sheetName = 'Sheet1'; const sheet = SpreadsheetApp.openById(spreadsheetId).getSheetByName(sheetName); sheet.appendRow([data.name, data.email, new Date()]); // 根据你的字段调整 return { success: true }; } function editRecord(data) { const spreadsheetId = 'YOUR_SPREADSHEET_ID'; const sheetName = 'Sheet1'; const sheet = SpreadsheetApp.openById(spreadsheetId).getSheetByName(sheetName); // 假设data包含rowIndex和更新的字段 sheet.getRange(data.rowIndex, 1).setValue(data.name); sheet.getRange(data.rowIndex, 2).setValue(data.email); return { success: true }; } // 处理POST请求的入口 function doPost(e) { const payload = JSON.parse(e.postData.contents); let result; switch(payload.action) { case 'add': result = addRecord(payload.data); break; case 'edit': result = editRecord(payload.data); break; default: result = { success: false, error: 'Invalid action' }; } return ContentService.createTextOutput(JSON.stringify(result)) .setMimeType(ContentService.MimeType.JSON); }
部署代理Web App
- 点击「部署」→ 「新部署」
- 类型选择「Web App」
- 执行身份选择「我,部署此Web App的人」
- 访问权限选择「任何拥有Google账户的用户」
- 复制部署后的Web App URL,后续会用到
2. 修改原Web App的服务端函数
在原Web App的Code.gs中,添加调用代理Web App的函数,替换原来直接操作表格的修改函数:
// 原Web App的Code.gs,保留你现有的handleRequest等函数,新增以下内容 const PROXY_WEB_APP_URL = 'YOUR_PROXY_WEB_APP_URL'; // 替换为代理Web App的URL function addRecord(data) { return callProxy('add', data); } function editRecord(data) { return callProxy('edit', data); } // 通用代理调用函数 function callProxy(action, data) { const options = { method: 'post', contentType: 'application/json', payload: JSON.stringify({ action: action, data: data }), headers: { 'Authorization': 'Bearer ' + ScriptApp.getOAuthToken() } }; try { const response = UrlFetchApp.fetch(PROXY_WEB_APP_URL, options); return JSON.parse(response.getContentText()); } catch (err) { Logger.log('Proxy call error: ' + err.toString()); return { success: false, error: err.toString() }; } }
3. 优化客户端错误处理
在Web App的前端HTML中,修改调用服务端函数的代码,添加明确的错误捕获:
<!-- 示例前端代码 --> <script> async function saveNewRecord() { const name = document.getElementById('name').value; const email = document.getElementById('email').value; try { const result = await google.script.run.addRecord({name, email}); if (result.success) { alert('记录添加成功'); // 刷新页面或更新列表 } else { alert('添加失败:' + result.error); } } catch (err) { console.error('保存错误:', err); alert('添加失败,请联系管理员'); } } async function updateRecord(rowIndex) { const name = document.getElementById(`name-${rowIndex}`).value; const email = document.getElementById(`email-${rowIndex}`).value; try { const result = await google.script.run.editRecord({rowIndex, name, email}); if (result.success) { alert('记录更新成功'); } else { alert('更新失败:' + result.error); } } catch (err) { console.error('更新错误:', err); alert('更新失败,请联系管理员'); } } </script>
可选:限制仅表格查看权限用户可操作
如果你需要确保只有拥有表格查看权限的用户才能使用修改功能,可以在原Web App的handleRequest函数中添加权限检查:
// 需先启用Drive API服务:编辑器→服务→添加Drive API function hasViewPermission(userEmail) { const spreadsheetId = 'YOUR_SPREADSHEET_ID'; const permission = Drive.Permissions.list(spreadsheetId, {q: `email='${userEmail}' and role='reader'`}); return permission.items && permission.items.length > 0; } // 修改handleRequest函数 function handleRequest(e) { // Check if the event object e is defined and has parameters var page = (e && e.parameter) ? e.parameter.page || 'index' : 'index'; // Default to 'index' if no page is specified or e is undefined try { var userEmail = Session.getActiveUser().getEmail(); Logger.log("User Email from Session: " + userEmail); // Debugging line if (!userEmail) { return HtmlService.createHtmlOutput("Could not retrieve user email. Please ensure you are logged in."); } // 新增权限检查 const hasPermission = hasViewPermission(userEmail); if (!hasPermission) { return HtmlService.createHtmlOutput("你没有操作权限"); } Logger.log("User is authorized: " + userEmail); // Debugging line return HtmlService.createTemplateFromFile(page).evaluate(); } catch (err) { Logger.log("Error in handleRequest: " + err.toString()); // Log the error return HtmlService.createHtmlOutput("An error occurred: " + err.toString()); } }
内容的提问来源于stack exchange,提问作者Anonymous
相关产品推荐
相关产品推荐

