Cross-domain requests stopped working due to no `Access-Control-Allow-Origin` header present in the response
I have an error reporting beacon I created using Google Apps script and it is published to run as myself and to be accessible to "anyone, even anonymous," which should mean that X-domain requests to GAS are allowed.
However, my browsers are now indicating there is no Access-Control-Allow-Origin
header on the response after the code posts to the beacon.
Am I missing something here? This used to work as recently as two months ago. So long as the GAS was published for public access, then it was setting the Access-Control-Allow-Origin
header.
In Google Apps Script:
Code.gsfunction doPost(data){
if(data){
//Do Something
}
return ContentService.createTextOutput("{status:'okay'}", ContentService.MimeType.JSON);
}
Client Side:
script.js$.post(beacon_url, data, null, "json");
Solution 1:
When making calls to a contentservice script I always have sent a callback for JSONP. Since GAS does not support CORS this is the only reliable way to ensure your app doesn't break when x-domain issues arrive.
Making a call in jQuery just add "&callback=?". It will figure everything else out.
var url = "https://script.google.com/macros/s/{YourProjectId}/exec?offset="+offset+"&baseDate="+baseDate+"&callback=?";
$.getJSON( url,function( returnValue ){...});
On the server side
function doGet(e){
var callback = e.parameter.callback;
//do stuff ...
return ContentService.createTextOutput(callback+'('+ JSON.stringify(returnValue)+')').setMimeType(ContentService.MimeType.JAVASCRIPT);
}
Solution 2:
I've lost a couple of hours with the same issue. The solution was trivial.
When you deploy the script as webapp, you get two URLs: the /dev
one and the /exec
one. You should use /exec
one to make cross domain POST requests. The /dev
one is always private: it requires to be authorized and doesn't set *Allow-Origin header.
PS.: The /exec
one seems to be frozen — it doesn't reflect any changes of code until you manually deploy it with a new version string (dropdown list in deploy dialog). To debug the most recent version of the script with the /dev
URL just install an alternative browser and disable it's web-security features (--disable-web-security in GoogleChrome).
Solution 3:
Just to make it simpler for those who are only interested in a POST request like me:
function doPost(e){
//do stuff ...
var MyResponse = "It Works!";
return ContentService.createTextOutput(MyResponse).setMimeType(ContentService.MimeType.JAVASCRIPT);
}
Solution 4:
I stumbled upon the same issue:
- calling
/exec
-urls from the browser went fine when running a webpage on localhost - throws crossorigin-error when called from a https-domain
I was trying to avoid refactoring my POST JSON-clientcode into JSONP (I was skeptical, since things always worked before).
Possible Fix #1
Luckily, after I did one non-CORS request (fetch()
in the browser from a https-domain, using mode: no-cors
), the usual CORS-requests worked fine again.
last thoughts
A last explanation might be: every new appscript-deployment needs a bit of time/usage before its configuration actually settled down at server-level.