Google Apps Script - Form to Sheets Cors issue

I have limited coding skills and have been using several AI tools to set up a form on my server to post to googles sheets

Posting to google sheets works OK but I continually get cors errors after submission.

I have gone through dozens of iterations of form script and apps scripts.

Initial versions attempted to confirm submission at the bottom of the form. This version attempts to redirect user to a "form submitted" URL (which I am OK with) - but still the cors error persists

 

RequestStatusPreflight Request (if problematic)HeaderProblemInvalid Value (if available)
 execblocked Access-Control-Allow-OriginMissing Header

This relates to

 fetch(scriptURL, {
              method: 'POST',
              mode: 'cors',  
 
Mode was a recent change.
 
The apps script runs ok in the scripts page when I Run doOptions and doPost
 
.htaccess has the following
Header set Access-Control-Allow-Origin "*"
Header set Access-Control-Allow-Methods "GET, POST, OPTIONS"
Header set Access-Control-Allow-Headers "Content-Type"
 
Form script and apps script copied below.
 
At this stage I would be happy to abandon both scripts if I could get a form script and an apps script that worked together which I could edit.
 

APPS SCRIPT
```
function doPost(e) {
try {
const sheet = SpreadsheetApp.openById('1aRa56pZPuToeBgdJZ-ldFdWhzoC7rlnGsJMRGbhatiA').getActiveSheet();
const formData = e.parameter;

sheet.appendRow([
new Date(),
formData.firstName,
formData.lastName,
formData.company === 'Optional' ? '' : formData.company,
formData.contactNumber,
formData.houseNumber,
formData.postcode,
formData.streetName,
formData.contactType,
formData.inquiry
]);

// Update the last modified timestamp
SpreadsheetApp.flush();
const now = new Date();
sheet.getRange(1, 1).setValue(now).clear();

// Create the redirect HTML content
var output = HtmlService.createHtmlOutput(
'<html><body><script>window.top.location.href = "https://mydomain.com/form-received";</script></body></html>'
);

// Add CORS headers to the response
output.addMetaTag('Access-Control-Allow-Origin', '*');
output.addMetaTag('Access-Control-Allow-Methods', 'POST, OPTIONS');
output.addMetaTag('Access-Control-Allow-Headers', 'Content-Type');

return output;
} catch (error) {
// In case of an error, redirect to the error page
var output = HtmlService.createHtmlOutput(
'<html><body><script>window.top.location.href = "https://mydomain.com/form-error";</script></body></html>'
);

return output;
}
}

 

function doOptions(e) {
Logger.log('OPTIONS request received'); // Log if OPTIONS request is received

var headers = {
'Access-Control-Allow-Origin': '*', // Allow all origins
'Access-Control-Allow-Methods': 'POST, OPTIONS',
'Access-Control-Allow-Headers': 'Content-Type'
};

var output = ContentService.createTextOutput('');
output.setMimeType(ContentService.MimeType.JSON); // Make sure to return JSON response
return output.setContent(JSON.stringify(headers)); // Send the CORS headers
}
```

======
Form and form script
```
<body>
<form id="contactForm" enctype="multipart/form-data">
<label for="firstName">First Name *</label>
<input type="text" id="firstName" name="firstName" placeholder="Enter your first name" required>

<label for="lastName">Last Name</label>
<input type="text" id="lastName" name="lastName" placeholder="Enter your last name">

<label for="company">Company</label>
<input type="text" id="company" name="company" value="Optional" class="optional-field">

<label for="contactNumber">Contact Number</label>
<input type="text" id="contactNumber" name="contactNumber" placeholder="Enter your contact number">

<div class="inline-fields">
<input type="text" id="houseNumber" name="houseNumber" placeholder="House Number">
<input type="text" id="postcode" name="postcode" placeholder="Postcode">
</div>

<label for="streetName">Street Name</label>
<input type="text" id="streetName" name="streetName" placeholder="Enter your street name">

<label for="contactType">Contact Type *</label>
<select id="contactType" name="contactType" required>
<option value="">-- Select --</option>
<option value="Customer">Customer</option>
<option value="Supplier">Supplier</option>
<option value="Other">Other</option>
</select>

<label for="inquiry">Your Inquiry</label>
<textarea id="inquiry" name="inquiry" rows="5" placeholder="Enter your inquiry here..."></textarea>

<button type="submit" id="submitButton">Submit</button>

<div id="formStatus"></div>
</form>

<script>
document.addEventListener('DOMContentLoaded', function() {
const form = document.getElementById('contactForm');
const formStatus = document.getElementById('formStatus');
const submitButton = document.getElementById('submitButton');
const scriptURL = 'https://script.google.com/macros/s/REMOVED/exec';
const companyField = document.getElementById('company');

companyField.addEventListener('focus', function() {
if (this.value === 'Optional') {
this.value = '';
this.classList.remove('optional-field');
}
});

companyField.addEventListener('blur', function() {
if (this.value === '') {
this.value = 'Optional';
this.classList.add('optional-field');
}
});

form.addEventListener('submit', e => {
e.preventDefault();

submitButton.disabled = true;
submitButton.textContent = 'Submitting...';
formStatus.style.display = 'none';

fetch(scriptURL, {
method: 'POST',
mode: 'cors',
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
},
body: new URLSearchParams(new FormData(form)).toString()
})
.then(response => {
if (!response.ok) {
throw new Error('Network response was not ok: ' + response.statusText);
}
return response.json(); // Parse the JSON response
})
.then(data => {
console.log('Form submission initiated:', data);
// Redirect on successful submission
window.location.href = "https://mydomain.com/form-received"; // Example redirect
})
.catch(error => {
console.error('Error!', error);
formStatus.className = 'error';
formStatus.textContent = 'Network error occurred. Please check your connection and try again.';
formStatus.style.display = 'block';

submitButton.disabled = false;
submitButton.textContent = 'Submit';
});
});
});
</script>

</body>
```

Solved Solved
0 2 5,403
1 ACCEPTED SOLUTION

This is the AppSheet Community.  AppSheet is a tool used to build no-code web apps that run on devices.  You will get better answers by posting your question on a Google forum that is dedicated to Google App Scripts.

View solution in original post

2 REPLIES 2

This is the AppSheet Community.  AppSheet is a tool used to build no-code web apps that run on devices.  You will get better answers by posting your question on a Google forum that is dedicated to Google App Scripts.

Thanks - Blame Gemini for sending me to the wrong place and me for not double checking ๐Ÿ™‚

Top Labels in this Space