不使用Drive API通过Google Apps Script存图片到云端硬盘遇CORS问题
解决Google Apps Script Web App图片上传的CORS问题
核心问题分析
你的方案触发CORS错误的根源有三点:
- 前端
fetch手动设置了错误的Content-Type,导致后端无法解析FormData格式的文件 - 后端未处理浏览器发送的预检OPTIONS请求
- 后端获取上传文件的方式错误,无法正确接收FormData中的文件内容
修复方案一:修正fetch+Web App代理逻辑
前端代码调整
移除fetch中手动设置的Content-Type头,浏览器会自动为FormData生成带boundary的正确multipart/form-data请求头:
await fetch(webAppUrl + '?action=uploadImage', { method: 'POST', mode: 'cors', headers: { // 移除手动设置的Content-Type,交由浏览器自动处理 'Authorization': `Bearer ${accessToken}` }, body: formData })
后端代码修正
添加OPTIONS请求处理(应对浏览器预检),并正确解析上传的文件内容:
function doPost(e) { if (e.parameter.action === 'uploadImage') { // 从postData中提取文件内容,转换为Blob对象 const imageBlob = Utilities.newBlob(e.postData.contents, e.postData.type, e.parameter.imageFile); const fileId = saveImageToDrive(imageBlob); const headers = { 'Access-Control-Allow-Origin': '*', 'Access-Control-Allow-Methods': 'POST, OPTIONS', 'Access-Control-Allow-Headers': 'Content-Type, Authorization' }; return ContentService.createTextOutput(fileId) .setMimeType(ContentService.MimeType.TEXT) .setHeaders(headers); } } // 专门处理浏览器的预检OPTIONS请求 function doOptions(e) { const headers = { 'Access-Control-Allow-Origin': '*', 'Access-Control-Allow-Methods': 'POST, OPTIONS', 'Access-Control-Allow-Headers': 'Content-Type, Authorization' }; return ContentService.createTextOutput('') .setMimeType(ContentService.MimeType.TEXT) .setHeaders(headers); } // 适配Blob参数的文件保存函数 function saveImageToDrive(imageBlob) { const folder = DriveApp.getFolderById(imgFolderID); const newFile = folder.createFile(imageBlob); return newFile.getId(); }
修复方案二:直接用google.script.run上传(无CORS风险,更简洁)
既然你已在使用google.script.run,可以直接用它完成文件上传,完全绕开CORS限制:
前端代码修改
替换原fetch上传逻辑,改用google.script.run:
// 替换原有的for循环上传代码 for(let i = 0; i < controls.imageUpload.files.length; i++){ const file = controls.imageUpload.files[i]; // 用google.script.run异步上传文件 await new Promise((resolve, reject) => { google.script.run .withSuccessHandler(fileId => { imageIds.push(fileId); resolve(); }) .withFailureHandler(error => { console.error('Error saving files', error); reject(error); }) .uploadImageToDrive(file); }); }
后端新增上传函数
// 直接接收google.script.run传递的文件Blob function uploadImageToDrive(fileBlob) { const folder = DriveApp.getFolderById(imgFolderID); const newFile = folder.createFile(fileBlob); return newFile.getId(); }
部署注意事项
- Web App部署时,权限需设置为**“任何人,甚至匿名”或“同一组织内的任何人”**,确保前端能正常访问
- 修改后端代码后必须重新部署并更新版本,否则修改不会生效
内容的提问来源于stack exchange,提问作者Lofton Gentry
相关产品推荐
相关产品推荐

