App Script与JavaScript的CORS跨域问题求助
解决Google Apps Script doPost接口的CORS问题
我有一个能生成HTML文件的JavaScript脚本,想把生成的HTML文件发送到指定邮箱,于是写了下面这个App Script的doPost接口:
function doPost(e) { let finalOutput = {}; const headers = { "Access-Control-Allow-Origin": "*", "Access-Control-Allow-Methods": "POST, OPTIONS", // Specify allowed methods "Access-Control-Allow-Headers": "*" // Specify allowed headers }; try { // 1. Récupération des deux paramètres principaux const rapportHTML = e.parameters.htmlContent; const destinataires = e.parameters.destinatairesContainer; console.log( "Rapport Html : " + rapportHTML + "\n" + "Destinataires :" + destinataires ); // Récupération des données pour le sujet const ligue = e.parameters.ligue || 'Not specified'; const categorie = e.parameters.categorie || 'Not Specified'; const matchDomicile = e.parameters.match_domicile || 'Unknown'; const matchVisiteur = e.parameters.match_visiteur || 'Unknown'; // 🛑 ADRESSE D'EXPÉDITION (Alias) (Optionnel - Si nécessaire pour GmailApp) const aliasExpediteur = ''; // Ex: 'ne-pas-repondre@votredomaine.com' if (!rapportHTML || !destinataires) { throw new Error("Contenu du rapport (htmlContent) ou Destinataires (destinatairesContainer) manquants."); } // 2. Construction du sujet const subject = `Rapport d'Expulsion: ${matchDomicile} vs ${matchVisiteur} (${ligue} / ${categorie})`; // 3. Configuration de l'e-mail const emailOptions = { to: destinataires, subject: subject, htmlBody: rapportHTML }; if (aliasExpediteur) { emailOptions.from = aliasExpediteur; } // 4. Envoi de l'e-mail avec GMAILAPP GmailApp.sendEmail(emailOptions); // 5. Réponse SUCCESS finalOutput = { success: true, message: `E-Mail sent to : ${destinataires}` }; } catch (error) { // 6. Réponse ERREUR finalOutput = { success: false, error: "Error sending Email: " + error.message, }; } // 7. FIX CORS (LIGNE CORRIGÉE ET SÉPARÉE) return ContentService.createTextOutput(JSON.stringify(finalOutput)) .setMimeType(ContentService.MimeType.JSON) .addCORSHeaders(headers); // Add CORS headers to error responses as well return finalOutput; } function addCORSHeaders(response, headers) { for (const header in headers) { response.addHeader(header, headers[header]); } return response; }
但每次通过网页按钮触发邮件发送时,都会出现如下CORS错误:
Access to fetch at 'https://script.google.com/macros/s/AKfycbxHm00gB_Uiv7lK78dDW68cBeFkXz_84G4Q4eJcBIV2gZ1Yowo1cqTgeAr-9kG_rOEB/exec' from origin 'null' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
我试过加setAccessControlAllowOrigin('*')但没用,现在卡壳了,求解决办法。
问题原因及解决步骤
1. 必须处理OPTIONS预检请求
浏览器发送POST请求前,会先发送OPTIONS预检请求确认服务器是否允许跨域请求。你的代码没处理这个请求,直接返回了POST的响应,导致预检失败,触发CORS错误。
2. 修复CORS头的设置方式
你自定义的addCORSHeaders函数没被正确调用,而且Google Apps Script的ContentService已经提供了更简单的方法设置CORS头,不用自己循环添加。
修改后的完整代码
function doPost(e) { let finalOutput = {}; // 先处理OPTIONS预检请求 if (e.method === 'OPTIONS') { return ContentService.createTextOutput('') .setMimeType(ContentService.MimeType.TEXT) .setAccessControlAllowOrigin('*') .setAccessControlAllowMethods('POST, OPTIONS') .setAccessControlAllowHeaders('*'); } try { // 1. 获取核心参数 const rapportHTML = e.parameters.htmlContent; const destinataires = e.parameters.destinatairesContainer; console.log("Rapport Html : " + rapportHTML + "\n" + "Destinataires :" + destinataires); // 获取邮件主题相关数据 const ligue = e.parameters.ligue || 'Not specified'; const categorie = e.parameters.categorie || 'Not Specified'; const matchDomicile = e.parameters.match_domicile || 'Unknown'; const matchVisiteur = e.parameters.match_visiteur || 'Unknown'; // 发件人别名(可选) const aliasExpediteur = ''; // 示例: 'ne-pas-repondre@votredomaine.com' if (!rapportHTML || !destinataires) { throw new Error("Contenu du rapport (htmlContent) ou Destinataires (destinatairesContainer) manquants."); } // 2. 构建邮件主题 const subject = `Rapport d'Expulsion: ${matchDomicile} vs ${matchVisiteur} (${ligue} / ${categorie})`; // 3. 配置邮件参数 const emailOptions = { to: destinataires, subject: subject, htmlBody: rapportHTML }; if (aliasExpediteur) { emailOptions.from = aliasExpediteur; } // 4. 发送邮件 GmailApp.sendEmail(emailOptions); // 5. 成功响应 finalOutput = { success: true, message: `E-Mail sent to : ${destinataires}` }; } catch (error) { // 6. 错误响应 finalOutput = { success: false, error: "Error sending Email: " + error.message, }; } // 7. 返回带CORS头的JSON响应 return ContentService.createTextOutput(JSON.stringify(finalOutput)) .setMimeType(ContentService.MimeType.JSON) .setAccessControlAllowOrigin('*'); }
额外注意事项
- 部署App Script时,要确保部署类型是Web应用,且权限设置为“任何人,甚至匿名”(如果你的场景允许)。
- 测试时尽量避免直接打开本地HTML文件(origin为null的情况),可以把HTML放到本地服务器(比如用Python的
http.server)或者线上托管平台测试,这样origin会是合法的域名。
内容的提问来源于stack exchange,提问作者Rapport Dexpulsion Rive-Sud R
相关产品推荐
相关产品推荐

