new google script version throwing javascript error - javascript

I have a Google Script-JSON-javascript webapp working but when I changed the JSON output, saved a new Google Script version, and published as web app, the webpage throws a CORB error.
Going back a version in GS, allowed it to work again. Why would a new GS version cause an error. Even with the same code but in a new version the error is still thrown. Is there a GS version caching issue? What I can do to update the version?
Working page with current version: https://arcacademy.ca/arc-academy-calendar-2018-2019/
Note: You can see in Console the JSON text being sent. The new code has the same format/structure, except changed the color values from hex to 1 to 10.
To tried to fix this by creating a new GS script but receive the same error:
Cross-Origin Read Blocking (CORB) blocked cross-origin response
https://script.google.com/macros/s/AKfycbyM51kxwQOYM3hRyrW7semhmUka2z2w-jU09KBPL38IxKapeQQ1/exec?callback=receivedCalendarEvents
with MIME type text/html. See
https://www.chromestatus.com/feature/5629709824032768 for more
details.
Here's the not working page throwing above error in console: https://arcacademy.ca/clone-of-arc-academy-calendar-2018-2019/
Google Script web app deployed with:
Execute as Me
Anyone, even Anonymous
Google Script code:
function doGet(e) {
if (e.parameter.method=="populate_events") {
var scriptProperties = PropertiesService.getScriptProperties();
var calendarId = scriptProperties.getProperty('calendarId') || 'primary';
var v = extractCalendarDateColors( calendarId, e.year );
return ContentService.createTextOutput(e.parameter.callback + "(" + JSON.stringify(v) + ")")
.setMimeType(ContentService.MimeType.JAVASCRIPT);
}
}
Javascript code for working page (src= is the only thing changed for error page):
<script>
calendarEvents = {};
function receivedCalendarEvents(jsonData) {
console.log('received',jsonData);
calendarEvents = JSON.parse(jsonData);
}
</script>
<script src="https://script.google.com/macros/s/AKfycbzMCDiTzxGx2cN5dtXqCG2gvxJ6FGZ_t6UuPiT-HyDesu2--EY/exec?callback=receivedCalendarEvents"></script>
<script>
Google Console Cloud -- I have set the following:
Enabled Calendar API
Added Apps Script Client ID
I feel like I'm lost in Google access land. Any help would be greatly appreciated!

Thank you Tanaike for the inspiration on this problem. The CORB (cross origin error) was, as you mentioned above, likely to do with javascript call.
I updated the javascript: https://script.google.com/macros/s/#####/exec?method=populate_events&year=2018
And updated the google script to use the parameters without throwing an error:
e.parameter.method
e.parameter.year
So it seems all the time I was getting the cross origin error, it was from a poorly formed javascript call and an error on the google script side, which returned an error and not a properly formed JSONP object.
Thank you for your help Tanaike!! :)

Related

Google Picker API Invalid origin value error

Today Google Picker stopped working in my Google Sheets add-on without any changes to the code. The error in the modal dialogue reads:
Invalid origin value.
The errors in console are:
Failed to execute 'postMessage' on 'DOMWindow': The target origin provided ('https://docs.google.com') does not match the recipient window's origin ('https://n-a6p4dqsl***d6wq-0lu-script.googleusercontent.com')
dropping postMessage.. was from unexpected window
dropping postMessage.. was from unexpected window
Invalid 'X-Frame-Options' header encountered when loading 'https://docs.google.com/picker?protocol=gadgets&origin=https%3A%2F%2Fdocs.google.com%2F&sdr=true&title&oauth_token=<oathToken>&developerKey=<developerKey>&hostId=n-a6p4dq***d6wq-0lu-script.googleusercontent.com&relayUrl=https%3A%2F%2Fn-a6p4dq***d6wq-0lu-script.googleusercontent.com%2Ffavicon.ico&nav=((%22documents%22%2Cnull%2C%7B%22selectFolder%22%3Atrue%2C%22parent%22%3A%22root%22%7D)%2C(%22documents%22%2Cnull%2C%7B%22dr%22%3Atrue%2C%22includeFolders%22%3Atrue%7D))&rpcService=qhurmoc5w4l7&rpctoken=xssf8g42xc2&thirdParty=true#rpctoken=xssf8g42xc2': 'ALLOW-FROM https://docs.google.com/' is not a recognized directive. The header will be ignored.
It maybe that the error is linked to this line of code where I do setOrigin():
var picker = new google.picker.PickerBuilder()
.addView(driveView)
.addView(drivesView)
.hideTitleBar()
.setOAuthToken(token)
.setDeveloperKey(DEVELOPER_KEY)
.setCallback(pickerCallback)
--> .setOrigin(google.script.host.origin)
.setSize(DIALOG_DIMENSIONS.width - 2,
DIALOG_DIMENSIONS.height - 2)
.build();
But this line is directly from the documentation of the Google Picker API and worked properly before. If I change google.script.host.origin, that returns https://docs.google.com as url to https://n-a6p4dqsl***6wcd6wq-0lu-script.googleusercontent.com, I get the same error and a new one, so that is not it.
I also cannot add this as as an authorized javascript origin in the GCP project as it returns the following error:
Invalid Origin: uses a forbidden domain
(This has been the case of a while)
This seems like a new error and I wasn't able to find an answer neither on Google's issues tracker nor on StackOverflow.
Anyone facing this as well or have an idea how it can be handled?
Putting an end, the only way to solve this is to remove the trailing slash after
From
docs.google.com/
To
docs.google.com
Contrary,
The google.script.host.orgin gives the "https://docs.google.com/" which causes the error. Hence you need to hard code as
"https://docs.google.com"
Google has made some changes recently which might have bubbled this issue.
UPDATE
You can use this function - and call - ...... setOrigin(getOrigin())
function getOrigin() {
var url = google.script.host.origin;
return url.substr(url.length - 1) === "/" ? url.substr(0, url.length - 1) : url;
}
Solution for use in a iframe
https://developers.google.com/apps-script/guides/dialogs#code.gs_2
code.gs
function showPicker() {
var html = HtmlService.createHtmlOutputFromFile('dialog.html')
.setWidth(600)
.setHeight(425)
.setSandboxMode(HtmlService.SandboxMode.IFRAME);
SpreadsheetApp.getUi().showModalDialog(html, 'Select a file');
}
.setSandboxMode(HtmlService.SandboxMode.IFRAME);
//can be removed or replaced with
.setXFrameOptionsMode(HtmlService.XFrameOptionsMode.ALLOWALL);
dialog.html
function getOrigin() {
var url = "https://mydomain.name/";
return url.substr(url.length - 1) === "/" ? url.substr(0, url.length - 1) : url;
}
Update
Now it works without any changes in the code.

Uploading a file using an HtmlService form in Google Apps always causes "server error" and a stack trace

I am trying to make a script for my Google spreadsheet in which I upload an XML file and process its data. I am able to create a form, display it in a modal dialog, but I get a strange error when I attempt to submit a form with a file: Nothing is logged for the error in Stackdriver Error Reporting. However, the web browser console logs the following error message:
Error: We're sorry, a server error occurred. Please wait a bit and try again.
The error message comes with a stack trace:
Zd https://n-z7hx4jjtvixobmaqkddve7tkcdyndjsnh3plmfq-0lu-script.googleusercontent.com/static/macros/client/js/2745927008-mae_html_user_bin_i18n_mae_html_user__en_gb.js:56
bf https://n-z7hx4jjtvixobmaqkddve7tkcdyndjsnh3plmfq-0lu-script.googleusercontent.com/static/macros/client/js/2745927008-mae_html_user_bin_i18n_mae_html_user__en_gb.js:71
G https://n-z7hx4jjtvixobmaqkddve7tkcdyndjsnh3plmfq-0lu-script.googleusercontent.com/static/macros/client/js/2745927008-mae_html_user_bin_i18n_mae_html_user__en_gb.js:15
J https://n-z7hx4jjtvixobmaqkddve7tkcdyndjsnh3plmfq-0lu-script.googleusercontent.com/static/macros/client/js/2745927008-mae_html_user_bin_i18n_mae_html_user__en_gb.js:99
Id https://n-z7hx4jjtvixobmaqkddve7tkcdyndjsnh3plmfq-0lu-script.googleusercontent.com/static/macros/client/js/2745927008-mae_html_user_bin_i18n_mae_html_user__en_gb.js:47
Ed https://n-z7hx4jjtvixobmaqkddve7tkcdyndjsnh3plmfq-0lu-script.googleusercontent.com/static/macros/client/js/2745927008-mae_html_user_bin_i18n_mae_html_user__en_gb.js:48
b https://n-z7hx4jjtvixobmaqkddve7tkcdyndjsnh3plmfq-0lu-script.googleusercontent.com/static/macros/client/js/2745927008-mae_html_user_bin_i18n_mae_html_user__en_gb.js:44
Of course, the stack trace doesn't help here, as it points to a huge minified JavaScript file on Google's servers.
I have tried replicating the examples in the current Google Apps documentation as well as a few old and recent examples I could find on StackOverflow, and the issue is always the same: When comes the time to submit the form data, the script crashes.
I know that this is specifically caused by the file input field. If I remove it, I'm able to submit the form and process its data. If I add the file input field, I get the error as soon as I submit the form.
I can tell the issue is not the file. I have tried uploading a big (125 kb) text file at first, followed by one a few bytes in size, and even not submitting any file at all, and I get the same error. I'm encountering this issue on both Chrome and Firefox, on two separate Google accounts.
Here is my Google script. The updateTracker method is called when clicking on a drawing object that I placed in the spreadhseet.
function updateTracker()
{
var thisUI = SpreadsheetApp.getUi();
var htmlUpdatePage = HtmlService.createHtmlOutputFromFile('myPage');
var updatePrompt = thisUI.showModalDialog(htmlUpdatePage, 'Update');
}
function digestXml(theForm) {
//var fileBlob = theForm.xmlFile;
var thisUI = SpreadsheetApp.getUi();
thisUI.alert("Test");
}
Here is my HTML file, "myPage":
<!DOCTYPE html>
<html>
<head>
<base target="_top">
<script>
// Prevent forms from submitting.
function preventFormSubmit() {
var forms = document.querySelectorAll('form');
for (var i = 0; i < forms.length; i++) {
forms[i].addEventListener('submit', function(event) {
event.preventDefault();
});
}
}
window.addEventListener('load', preventFormSubmit);
function submitXml(objForm)
{
google.script.run.withSuccessHandler(updateUrl).digestXml(objForm);
}
function updateUrl(url) {
var div = document.getElementById('output');
div.innerHTML = 'Got it!';
}
</script>
</head>
<body>
<form id="xmlForm" onsubmit="submitXml(this)">
<input type="file" value="Browse" name="xmlFile" />
<input type="submit" value="Digest" />
</form>
<div id="output"></div>
</body>
</html>
I can tell that the issue occurs precisely when trying to pass objForm from the HTML to the Google Script. I'm able to write to the console right before the line google.script.run.withSuccessHandler(updateUrl).digestXml(objForm); in HTML, but I don't get to thisUI.alert("Test"); in the Google Script. If I remove the parameter objForm from digestXml() in the HTML, the crash does not occur.
It appears that the issue only occurs in a recently released version of Google App's scripting interface, "V8".
When I create a script, I am prompted to use this version of their scripting interface. Trusting Google to test their functionalities, I accepted without thinking.
If I edit my script's configuration file to use STABLE instead of V8, I do not encounter the issue. If you're having this issue, here's how to do that:
Open the Script Editor.
In the top menu, select View > Show manifest file.
In the files list, open appsscript.json.
Replace "runtimeVersion": "V8" with "runtimeVersion": "STABLE"
Save.
This is however alarming as I presume the current stable version will be deprecated eventually in favor of V8. I logged an issue for this: https://issuetracker.google.com/issues/149980602

How do I link an external js file that returns code 302

I am trying to combine Github Pages with Google Apps Script so I can have Server Side Scripting with Github Pages. I try to connect to the Google Script web app using:
<script src="https://script.google.com/macros/s/NO_LINK_FOR_YOU/dev">
</script>
(I need that /dev there, google script says nothing was returned when I don't use it.)
That is supposed to (and does) return:
return ContentService.createTextOutput("window.onload = function(){document.getElementById(\"request\").innerHTML = \"Generated: " + generateRandomNumber(10, 42) + "\";}");
Which outputs this:
window.onload = function(){document.getElementById("request").innerHTML = "Generated: 28";}
(Of course, it would not always be 28.)
When I load this into the browser, it does nothing. I looked in inspect element and it says that it's returning the code 302 (Temporarily Moved). This is usually used for redirects, and content service always makes the browser redirect "for security reasons", so this is expected.
But how can I get the browser to follow that redirect and get the script from there? Can I even do that?
In this case, a mimetype error occurs, since mimetype is not set. So please add setMimeType() as follows.
return ContentService
.createTextOutput("window.onload = function(){document.getElementById(\"request\").innerHTML = \"Generated: " + generateRandomNumber(10, 42) + "\";}")
.setMimeType(ContentService.MimeType.JAVASCRIPT);

Chrome webRequest responseBody (POST) error

I am building a Chrome extension and trying to log some requests: the ones with POST parameters (plain text data)
This is the code I'm using:
var requestFilter = {urls: ["<all_urls>"]};
var extraInfoSpec = ['requestHeaders','requestBody','blocking']; // note: without 'requestBody' it works perfectly, but there's no POST data available.
var handler = function( details ) {
console.log(details);
};
chrome.webRequest.onBeforeSendHeaders.addListener(handler, requestFilter, extraInfoSpec);
I use requestHeaders and blocking for other things that are not in the example (don't worry about them now)
I am getting this error at page load: Uncaught Error: Invalid value for argument 2. Property '.1': Value must be one of: [requestHeaders, blocking].
I am develping under Chrome Version 36.0.1985.125 m
Form chrome webRequest documentation: Stable since Chrome 23. Contains the HTTP request body data. Only provided if extraInfoSpec contains 'requestBody'.
Any experience with this error? Any known solution? How can I solve this?
You are listening to the wrong event.
If you look at the documentation, onBeforeSendHeaders does not list requestBody in the callback details.
It is, however, available in onBeforeRequest.
So, if you need both the headers and the body, you have to correlate the two events by requestId.

NS_ERROR_FAILURE with JS XMLHttpRequest

I'm trying to load the source of a web page, as shown in "Javascript:The Definitive Guide" p.481, using firefox.
Here's my code:
var request = new XMLHttpRequest();
request.open("GET", "http://finance.yahoo.com/q?s=PG", false);
request.send(null);
if (request.status==200) { alert(request.responseText); }
else {alert("Error "+request.status + ": "+request.statusText);}
</script>
Firebug shows the GET statement, followed by 200 OK X 338ms.
Which looks like it was successful (code 200).
But the next Firebug line says: NS_ERROR_FAILURE, request.send(null);, with no further explanation.
and neither alert gets executed.
It doesn't help if I use help mode, and doesn't run in Chrome either. I don't have a popup or cookie or ad blocker running.
The page loads fine in perl with an LWP get().
If this is an inevitable cross-domain taboo, why doesn't the "definitive guide" say so?
I understand that JSONP returns JSON. I don't want that - I want just a string with the raw source, like with the perl LWP get().
Is this impossible with Javascript?
I suppose I could write a batch file which uses perl to get the source and put it into a JSON file whose name is hard-coded into the JS. But I'd like to avoid that sort of kludge.
In case it helps,
I have run into this problem a couple times before, and ran into it again. If the answer to this question doesn't help you, try adding the following lines which helped me:
request.overrideMimeType('text/xml; charset=UTF-8'); // needed to get utf8 req's to work
or this debug line (which you can monitor on the web console of your browser)
request.onreadystatechange = function() {console.log("statechanged. url= " + url);};
before your
request.open()
where url is a var that holds the url you are trying to request. Sometimes it will give you that cryptic error if there is a problem getting the url, in my (last) case, it was because the url was malformed. Hope that helps someone out there.

Categories

Resources