Google Picker API Invalid origin value error - javascript

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.

Related

sheet.cssRules throws error on inner pages but works fine on homepage

I am using this function in my Wordpress site's custom javascript.
var addRule = (function (sheet) {
if(!sheet) return;
return function (selector, styles) {
console.log(sheet.cssRules)
if (sheet.insertRule) return sheet.insertRule(selector + " {" + styles + "}", sheet.cssRules.length);
if (sheet.addRule) return sheet.addRule(selector, styles);
}
}(document.styleSheets[document.styleSheets.length - 1]));
The problem here is the above function works fine on homepage but,
Throws Uncaught DOMException: Failed to read the 'cssRules' property from 'CSSStyleSheet': Cannot access rules on inner pages.
Here is the link to my site,
Homepage //here you will see no error in console
Inner Page //here you will see an error in console
as per my research, this error is caused by Cross-Origin Resource Sharing (CORS),
but why it is working on Homepage?
No doubt that the problem is caused by CORS. I suggest you to console.log(document.styleSheets) and see the href of the element to check which stylesheet is getting passed to your addrule() after doing this document.styleSheets.length - 1, the stylesheet's href should be same as your domain.
It's not going to work without you including "../" before the sheet.cssRule. Just go ahead and count the depth of your internal file and add "../" to be exactly equal to that value.
Writing something like "../../../../sheet.cssRule" instead of "sheet.cssRule" should get the problem solved.
I understand you code is absolutely fine when we compare both pages and also try close console.log with (;) semi colon in your script.
console.log(sheet.cssRules);

new google script version throwing javascript error

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!! :)

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);

Prevent OpenCPU javascript error popup window

I have an error related to CORs for a test deployment of OpenCPU, which may get its own question, but for now I'd like it to fail without notifying the end user via a popup - is this possible?
The error I see in the browser console is due to the website swapping TLD as you navigate:
XMLHttpRequest cannot load http://104.XX.3.XX/ocpu/library/predict/R/. The 'Access-Control-Allow-Origin' header has a value 'http://www.XXXX.com' that is not equal to the supplied origin. Origin 'http://www.XXXX.dk' is therefore not allowed access.
And a popup appears:
I'd like to ensure if there are possible future errors it doesn't detract for the user experience - in this case OpenCPU is used for a non-essential function of the website.
Found via a non-specific to OpenCPU question
// suppress alerts
window.alert = function ( text ) { console.log( 'tried to alert: ' + text ); return true; };

Getting the current domain name in Chrome when the page fails to load

If you try to load with Chrome: http://sdqdsqdqsdsqdsqd.com/
You'll obtain:
ERR_NAME_NOT_RESOLVED
I would like, with a bookmarklet, to be able to get the current domain name and redirect it to a whois page in order to check if the domain is available.
I tried in the console:
window.location.href
but it outputs:
"data:text/html,chromewebdata"
Is there any way to retrieve the failed URL?
The solutions given by others didn't work (maybe because I was getting a different error or have a newer version: Chrome 55):
document.querySelector('strong[jscontent="hostName"]').textContent
but the same can be achieved via:
document.querySelector('#reload-button').url
A potentially more future-proof version (from Thomas's comment)
loadTimeData.data_.summary.failedUrl
So a cross-version solution incorporating all workarounds:
var url = (l‌​ocation.href === 'data‌​:text/html,chromeweb‌​data'
&& loadTimeData.data_.summary.failedUrl
|| document.querySelector('#reload-button').url
) || location.href;
var hostname = (l‌​ocation.href === 'data‌​:text/html,chromeweb‌​data'
&& loadTimeData.data_.summary.hostName
|| document.querySelector('strong[jscontent="hostName"]').textContent
) || location.hostname;
On the Chrome error page, location.href doesn't point to the domain you tried to visit, since it's an internally-hosted page.
However, the domain name you tried to visit is available if you expand the "Show Details" link.
You can run this code in console (or a bookmarklet) to parse out the domain name:
document.querySelector('strong[jscontent="hostName"]').textContent
A modified version of nderscore's since you'll need to have an if statement for the return of the correct one.
function getUrl () {
if(window.location.hostname == "") {
return document.querySelector('strong[jscontent="hostName"]').textContent
} else{
return window.location.href;
}
}
While looking in source code of html page using Developer Tools (right-click on a web page, and select Inspect Element), I've found that full original failed URL is in a variable called
loadTimeData.data_.summary.failedUrl
In my case I have to update some 'incorrect part' of auto generated URL to 'correct part'. So I've created bookmarlet like this:
javascript: location.assign(loadTimeData.data_.summary.failedUrl.replace('IncorrectPart','CorrectPart'));

Categories

Resources