为何已包含可写字段仍触发Google Drive API v3 writableFieldRequired错误?
问题:调用Drive API v3创建带锚点评论报writableFieldRequired错误
在Google Apps Script中使用UrlFetchApp调用Drive API v3创建带锚点的评论时,尽管已传入可写属性content和anchor,仍抛出400错误,错误类型为writableFieldRequired。
背景说明:Drive API v2不支持添加锚点评论,但v3文档显示该功能已可用;截至2023年3月,GAS内置Drive服务仍为v2,因此采用外部调用方式。
原代码示例
function testComment() { var doc = DocumentApp.getActiveDocument(); var token = ScriptApp.getOAuthToken(); var docId = doc.getId(); var urlDriveCommentsV3 = 'https://www.googleapis.com/drive/v3/files/' + docId + '/comments?fields=id'; var anchor = { 'r': 'head', 'a': [ { 'txt': { 'o': 1, 'l': 6 } } ] }; var commentv3 = { 'content': 'This is a test comment 01', 'anchor': anchor }; var options = { 'method': 'post', 'headers': { 'Authorization': 'Bearer ' + token, 'Accept': 'application/json', 'Content-Type': 'application/x-www-form-urlencoded' }, 'payload': commentv3, 'muteHttpExceptions': true }; var result = UrlFetchApp.fetch(urlDriveCommentsV3, options); Logger.log(result); };
错误日志
{ "error": { "code": 400, "message": "At least one writable field must be specified in the resource body.", "errors": [ { "message": "At least one writable field must be specified in the resource body.", "domain": "global", "reason": "writableFieldRequired" } ] } }
解决方法
错误根源在于请求的Content-Type设置错误,且payload未正确序列化为JSON格式:
- Drive API v3要求POST请求的
Content-Type为application/json,原代码使用的application/x-www-form-urlencoded会导致API无法解析请求体中的字段 - 直接传入JavaScript对象作为
payload时,UrlFetchApp会自动按表单编码处理,而非JSON格式
修改步骤:
- 将请求头的
Content-Type改为application/json - 使用
JSON.stringify()将评论对象序列化为JSON字符串作为payload - 确保脚本已获得Drive API的授权权限(首次运行时会触发授权流程)
修改后的代码示例
function testComment() { var doc = DocumentApp.getActiveDocument(); var token = ScriptApp.getOAuthToken(); var docId = doc.getId(); var urlDriveCommentsV3 = 'https://www.googleapis.com/drive/v3/files/' + docId + '/comments?fields=id'; var anchor = { 'r': 'head', 'a': [ { 'txt': { 'o': 1, 'l': 6 } } ] }; var commentv3 = { 'content': 'This is a test comment 01', 'anchor': anchor }; var options = { 'method': 'post', 'headers': { 'Authorization': 'Bearer ' + token, 'Accept': 'application/json', 'Content-Type': 'application/json' }, 'payload': JSON.stringify(commentv3), 'muteHttpExceptions': true }; var result = UrlFetchApp.fetch(urlDriveCommentsV3, options); Logger.log(result); };
内容的提问来源于stack exchange,提问作者Majal
相关产品推荐
相关产品推荐

