部署为Web应用的Google Apps Script调用时HTTP 401错误问题
解决UrlFetch调用GAS Web应用时的HTTP 401错误
我之前碰到过几乎一模一样的问题!好好的脚本跑了几个月,突然就报401 Unauthorized,排查下来大多是Google的部署配置隐性变化或者权限政策调整导致的,给你几个实用的排查和解决方向:
1. 先盯紧Web应用的部署配置
别不信,很多时候问题就出在你以为没改的部署设置上
- 打开Script A的部署管理页:右上角「部署」→「管理部署」
- 重点检查当前活跃版本的两个核心设置:
- 「执行权限」:如果你的Web应用需要调用你的个人资源(比如Sheet),必须选「以我自己的身份执行」;如果只是返回静态内容,选「以访问者身份执行」也可以,但关键是下面的「谁可以访问」必须是「任何人,甚至匿名」
- 要是你最近重新部署过,很可能不小心把「谁可以访问」改成了「仅限组织内」或者「仅限我自己」,这直接会锁死外部访问
- 另外确认你用的是最新的部署URL,旧的部署链接可能因为版本过期被Google限制访问
2. 排查Bearer授权头的冲突
虽然你把Script A设为了任何人可访问,但如果请求里带了Bearer头,Google会自动尝试验证这个令牌,反而可能触发权限冲突:
- 先做个极简测试:去掉UrlFetch里的Bearer授权头,直接调用Script A的Web应用URL,看能不能正常返回内容
- 如果去掉后正常,那就是授权头的问题:
- 检查令牌生成逻辑,比如是不是用了
ScriptApp.getOAuthToken()?这个令牌的权限范围可能因为Google的政策更新被收紧了,或者定时任务里的令牌获取逻辑出了问题 - 既然Script A已经允许任何人访问,完全可以直接去掉这个Bearer头,避免不必要的权限验证
- 检查令牌生成逻辑,比如是不是用了
3. 检查Google服务更新的影响
你说问题是两周前出现的,刚好赶上Google可能推送服务更新的周期:
- Apps Script的OAuth 2.0权限范围最近有过收紧,之前有效的令牌现在可能无法访问公开Web应用
- 公开Web应用的访问策略也有调整,现在即使设为任何人访问,带无效或不匹配的授权头也会被拒绝
4. 用极简脚本定位问题
把Script A的doGet简化到极致,排除参数处理的干扰:
function doGet(e) { return ContentService.createTextOutput("测试成功"); }
然后用另一个脚本做两种测试:
function testWebApp() { const webAppUrl = "你的Script A部署URL"; // 测试1:不带授权头的请求 try { const res1 = UrlFetchApp.fetch(webAppUrl); console.log("无授权头返回:", res1.getContentText()); } catch(err) { console.error("无授权头错误:", err); } // 测试2:带Bearer头的请求 try { const token = ScriptApp.getOAuthToken(); const options = { headers: { "Authorization": `Bearer ${token}` } }; const res2 = UrlFetchApp.fetch(webAppUrl, options); console.log("带授权头返回:", res2.getContentText()); } catch(err) { console.error("带授权头错误:", err); } }
对比两种请求的结果,就能快速定位是授权头的问题还是部署设置的问题
5. 查看Web应用的执行日志
在Script A里点击「查看」→「日志」,看看有没有更详细的错误信息,Google经常会在日志里给出401的具体原因,比如令牌无效、权限范围不足等
我当时的问题就是重新部署时手滑把「谁可以访问」改成了组织内访问,改回「任何人,甚至匿名」就立马好了。后来还发现,带Bearer头的请求如果令牌没有包含Web应用的访问权限,也会被拒绝,所以如果不需要授权,直接去掉授权头反而更稳妥。
内容的提问来源于stack exchange,提问作者Q_C
相关产品推荐
相关产品推荐

