Cors issue with app script

72 views
Skip to first unread message

Rapport D'expulsion Rive-Sud / Richelieu-Yamaska

unread,
Sep 30, 2025, 8:51:12 AMSep 30
to Google Apps Script Community
Why i always get ccess 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.

when i try to call the fetch from my script?

i set it as an web application and everyone has access.

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 || 'Non spécifiée';
    const categorie = e.parameters.categorie || 'Non spécifiée';
    const matchDomicile = e.parameters.match_domicile || 'Inconnu';
    const matchVisiteur = e.parameters.match_visiteur || 'Inconnu';
   
    // 🛑 ADRESSE D'EXPÉDITION (Alias) (Optionnel - Si nécessaire pour GmailApp)
    const aliasExpediteur = ''; //

    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 envoyé avec succès à : ${destinataires}`
    };

  } catch (error) {
    // 6. Réponse ERREUR
    finalOutput = {
        success: false,
        error: "Erreur Apps Script lors de l'envoi d'e-mail: " + 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;
     }
Message has been deleted

DimuDesigns

unread,
Sep 30, 2025, 9:19:12 AMSep 30
to Google Apps Script Community

Google Apps Script Web App triggers do not support CORS.

CORS requires support for OPTIONS as an HTTP verb for pre-flight requests. Unfortunately, GAS Web Apps only support POST and GET requests.

Moreover, there is no 'addCORSHeaders()' method available on TextOutput instances. And defining that method on the top-level global object is non-sensical.

This is likely AI generated code. AI is known to be wrong on occasion. 

Kildere S Irineu

unread,
Sep 30, 2025, 9:43:11 AMSep 30
to google-apps-sc...@googlegroups.com

Of course. This is one of the most common and frustrating problems developers face when starting with Google Apps Script (GAS) Web Apps. The user in the Google Group, DimuDesigns, is 100% correct, and their explanation is the key to understanding the issue.

Let's break down exactly why you're seeing this error, why your code isn't fixing it, and what the correct solutions are.

The Core Problem: The CORS "Pre-flight" Request

The error message you're seeing is not from your POST request. It's from a special, automatic request that the browser sends before your POST request. This is called a CORS Pre-flight Request.

Here's the process:

  1. Your Code Tries fetch: Your JavaScript on your local machine (origin: 'null') tries to send a POST request to the Google Script URL.

  2. The Browser Intervenes: Because you are making a "non-simple" request (a POST request, often with a Content-Type header like application/json), the browser's security policy says: "Hold on! I can't just send this data to a different domain. I need to ask for permission first."

  3. The OPTIONS Pre-flight: The browser automatically sends an OPTIONS request to the Google Script URL. It's like the browser is knocking on the door and asking, "Hey, I'm about to send a POST request from origin: 'null'. Are you going to allow that?"

  4. Google Apps Script's Limitation: This is the critical failure point. As DimuDesigns correctly stated, Google Apps Script Web Apps can only handle GET and POST requests. They do not understand or respond to OPTIONS requests.

  5. The Failure: The Google server receives the OPTIONS request, doesn't know what to do with it, and likely responds with a standard Google HTML page (like a login redirect) or nothing at all. It certainly does not respond with the Access-Control-Allow-Origin: * header the browser was looking for.

  6. The Browser Blocks You: The browser sees that the OPTIONS request failed to get permission. For your security, it cancels the actual POST request. It never even sends it.

  7. The Error: The browser then shows you the CORS error message you're seeing.

This is why your code inside doPost is never even running. You are trying to add the CORS headers in a function that is never called because the pre-flight request fails first.

Why Your Code Doesn't Work

  • addCORSHeaders(headers): As the expert noted, ContentService.createTextOutput() does not have a method called addCORSHeaders. This was likely an AI hallucination. The correct way to add headers is by chaining methods, but even that wouldn't solve the pre-flight problem.

  • Setting Headers Inside doPost: You can't solve a permission problem (the OPTIONS request) from inside the function that you don't have permission to run yet (the POST request).

Solutions and Correct Approaches

Since you cannot use a standard CORS-enabled fetch with a POST request, you must use a workaround. Here are the most common ones.

Solution 1: Use a Standard HTML Form Submission (Recommended for POST)

This is the simplest way to send POST data to a GAS Web App from a browser. Traditional form submissions are not subject to the same CORS pre-flight checks.

On your client-side (your local HTML file):

Html
<!DOCTYPE html>
<html>
<head>
    <title>Send Report</title>
</head>
<body>
    <h1>Submit Your Report</h1>
    
    <form id="reportForm" method="post" action="YOUR_WEB_APP_URL_HERE">
        <input type="hidden" name="htmlContent" id="htmlContentInput">
        <input type="hidden" name="destinatairesContainer" id="destinatairesInput">
        <!-- Add other inputs for ligue, categorie, etc. -->
        <input type="hidden" name="ligue" value="Ligue Exemple">
        <input type="hidden" name="categorie" value="U15">
        <input type="hidden" name="match_domicile" value="Team A">
        <input type="hidden" name="match_visiteur" value="Team B">

        <button type="submit">Send Email</button>
    </form>

    <script>
        document.getElementById('reportForm').addEventListener('submit', function(e) {
            // Populate the hidden fields with your data before submitting
            const myHtml = "<h1>This is the report</h1><p>Some details...</p>";
            const recipients = "te...@example.com,te...@example.com";

            document.getElementById('htmlContentInput').value = myHtml;
            document.getElementById('destinatairesInput').value = recipients;
            
            console.log('Submitting form...');
            // The form will now submit normally.
        });
    </script>
</body>
</html>

Your doPost(e) function in Apps Script will work almost exactly as you wrote it, because it's designed to handle form parameters. The main drawback is that the user will be redirected to the JSON response page after submission.

Solution 2: JSONP (Only for GET Requests)

If you only need to retrieve data (not send a large HTML body), you can change your function to doGet(e) and use a technique called JSONP, which cleverly bypasses CORS by using <script> tags. This is not suitable for your current doPost use case but is good to know.

Solution 3: Use a Server-Side Proxy (Advanced)

The most robust solution for a real application is to have your own server (e.g., using Node.js, Python, or another Google Cloud Function) that your front-end can call. Your server then calls the Google Apps Script URL. Server-to-server communication is not restricted by CORS.

Flow: Your Browser fetch -> Your Server -> Google Apps Script

This is overkill for a simple project but is the professional way to handle this limitation in a larger system.


In summary: The expert was right. You cannot fix this CORS error by adding headers in doPost. You must change your client-side approach to use a method that avoids the OPTIONS pre-flight request, with a standard HTML form submission being the most direct solution for your case.


--
You received this message because you are subscribed to the Google Groups "Google Apps Script Community" group.
To unsubscribe from this group and stop receiving emails from it, send an email to google-apps-script-c...@googlegroups.com.
To view this discussion visit https://groups.google.com/d/msgid/google-apps-script-community/995014da-1306-4d6a-af69-e0ea661a3508n%40googlegroups.com.

DimuDesigns

unread,
Sep 30, 2025, 10:04:08 AMSep 30
to Google Apps Script Community
Kildere, did you use AI to generate that thorough analysis?

If you did, would you mind sharing which tools you used and the accompanying prompts?

Kildere S Irineu

unread,
Sep 30, 2025, 11:50:09 AMSep 30
to google-apps-sc...@googlegroups.com
Olá


DimuDesigns 


Sim, utilizei inteligência artificial para gerar essa análise. 
No entanto, o resultado depende bastante da forma como a gente estrutura as perguntas e direciona a IA, usando técnicas de prompt engineering. O segredo está justamente em saber como pedir. 
Usei Gemini. 

Segue meu linkdin

Atenciosamente, 



Reply all
Reply to author
Forward
0 new messages