No response data received from a jquery post to Google App Script - javascript

I am sending a post request to a Google App Script webapp from a webpage under different domain.
The doPost method at the GAS side handles the request, and returns a string.
I can see the request reaching the server, but no response is received at the client side.
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script>
function myFunc() {
$.post("https://googlewebappURL", postdata).done(function(responsedata) {
alert("Data Loaded: " + responsedata);
});
};
</script>
The alert call does not happen.
The post does reach the web app, my logs confirm that.
Am I doing something wrong here?

I think that your javascript works fine. For your situation, I think of the following confirmation points.
Confirmation points :
It seems that postdata is not defined.
When the script was modified, whether the script version was updated and deployed Web Apps as the new version. How to deploy Web Apps is as follows.
On the Script Editor
Publish
Deploy as Web App
Create new Project version
At Execute the app as, select "your account"
At Who has access to the app, select "Anyone, even anonymous"
Click "Deploy"
Copy "Current web app URL"
Click "OK"
The detail of deploying Web Apps is here.
Even if you confirm above points, if the problem is not solved, can you try a simple sample as follows? If the modified your script didn't work, you can also use a curl sample. When the sample works, you retrieve value.
Sample :
Google Apps Script : code.gs
function doPost(e) {
return ContentService.createTextOutput(e.parameter.key);
}
Modified your script :
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script>
$(function() {
var postdata = {key: "value"}; // Added
$.post("https://googlewebappURL", postdata).done(function(responsedata) {
alert("Data Loaded: " + responsedata);
});
});
</script>
curl sample :
curl -L -d "key=value" "https://googlewebappURL"
If above samples didn't work, can I ask you about your doPost()? If I misunderstand your question, I'm sorry.

Related

Google Script HTML form from Library throws error Uncaught

I have a library with HTML-form like this:
code.gs:
function openDialog() {
SpreadsheetApp.getUi().showModalDialog(HtmlService.createHtmlOutputFromFile("h"), "Test" );
}
function hello() {
console.log('booo');
}
h.html:
<!DOCTYPE html>
<html>
<head>
<base target="_top">
</head>
<body>
<button id="b">Click me</button>
<script>
var b = document.getElementById('b');
b.onclick = function() {
google.script.run
.withSuccessHandler(function(str){window.alert("executed");})
// .withFailureHandler(function(error){window.alert("failed");})
.hello();
}
</script>
</body>
</html>
I shared this script for view and deployd it as a library. Next I created a bound script in Google Sheet with this code:
function onOpen() {
SpreadsheetApp.getUi().createMenu('test').addItem('run', 'myFunction').addToUi();
}
var hello = function() {};
function myFunction() {
TT.openDialog();
}
I've added the library with identifier: TT.
Next I refreshed my Google Sheet file with bound code to see the menu "test", ran test > run. The HTML-window appeared. When I clicked the button, nothing happened. When I opened console, I saw the error:
This error does not appear if I do not use library.
I have experienced the same situation with you. In my case, the reason of the issue was due to the authorization at the library side.
When the authorization process for using the scopes in the library is NOT done at the library side, I confirmed that the error of Uncaught occurred.
When the authorization process for using the scopes in the library is done at the library side, I confirmed that the error of Uncaught didn't occur.
Namely, in my environment, I confirmed that when the library is used for your situation, it was required to authorize the scopes for both the client side and the library side.
So, as a workaround, I used the following flow.
Workaround:
Create a Google Apps Script library.
Please copy and paste your script of code.gs and h.html to the standalone script or the container-bound script.
Deploy the Google Apps Script as the library.
In your script, for example, please directly run hello() at the library side, and authorize the scopes.
Install the library to the client side and load the library from the client side.
Please run myFunction() at the client side.
By this flow, when you run run at the custom menu and click the button, the dialog of executed is opened.
Note:
In this case, when I wanted to make users use the client script, it was required to authorize the scopes for both the client side and the library side. I thought that this may be a little inconvenient.
So, how about reporting this for the Google issue tracker? Ref Unfortunately, I couldn't find the issue tracker with the same situation.
Added:
As the method for authorizing the scopes at the library side from the client side, I would like to propose to use Web Apps. I thought that when the Web Apps is used, the authorization of the library side can be done at the client side. By this, I thought that the inconvenience may be resolved a little.
Please do the following flow.
1. Library side.
Please copy and paste the following scripts.
Google Apps Script: code.gs
function openDialog() {
SpreadsheetApp.getUi().showModalDialog(HtmlService.createHtmlOutputFromFile("h"), "Test" );
}
function hello() {
console.log('booo');
}
function doGet() {
return HtmlService.createHtmlOutput("ok");
}
HTML: h.html
<!DOCTYPE html>
<html>
<head>
<base target="_top">
</head>
<body>
<button id="b">Click me</button>
<script>
var b = document.getElementById('b');
b.onclick = function() {
google.script.run
.withSuccessHandler(function(str){window.alert("executed");})
// .withFailureHandler(function(error){window.alert("failed");})
.hello();
}
</script>
</body>
</html>
2. Deploy Web Apps at library side.
Please deploy Web Apps at the library side. About the method for this, you can see the official document. Ref The detail setting is as follows.
Execute as: User accessing the web app
Who has access: Anyone with Google account
3. Deploy as library.
Please deploy as the library. Ref
4. Client side.
Please install the library to the client side. And, please copy and paste the following scripts. In this case, please replace https://script.google.com/macros/s/###/exec with your Web Apps URL.
function onOpen() {
SpreadsheetApp.getUi().createMenu('test').addItem('auth', 'auth').addItem('run', 'myFunction').addToUi();
}
var hello = function() {};
function myFunction() {
TT.openDialog();
}
function auth() {
const html = HtmlService.createHtmlOutput(`<input type="button" value="Authorize" onclick="window.open('https://script.google.com/macros/s/###/exec', '_blank');google.script.host.close()">`);
SpreadsheetApp.getUi().showDialog(html);
}
5. Testing.
At first, please run auth at the custom menu. By this, you can authorize the scopes of both the client side and the library side. When the new tab is not opened when auth is run, please run auth() at the script editor again.
As the next step, please run run. By this, your dialog is opened. And, when both authorizations (client and library side) with auth has already been finished, when you click the button, the dialog of executed is opened.
References:
Web Apps
Taking advantage of Web Apps with Google Apps Script

Trouble accessing Google Sheet as a TSV file

For the past few years, I've been using Sheets as a data source for a web app by using the following code to turn the id into a direct link to a TSV file:
let id="1zD3eIL8LCTJ8F_8U3kWA6k5WPJNKr_UZ_93bnARlMxQ"
let str="https://docs.google.com/spreadsheets/d/"+id+"/export?format=tsv";
var xhr=new XMLHttpRequest();
xhr.open("GET",str);
xhr.onload=function() {/* act on data */ };
xhr.send();
xhr.onreadystatechange=function(e) {
if ((xhr.readyState === 4) && (xhr.status !== 200)) {
/* Show error */
}
It still works on old files, but new ones yield a CORS error:
Access to XMLHttpRequest at 'https://doc-00-0g-sheets.googleusercontent.com/export/l5l039s6ni5uumqbsj9o11lmdc/5filqetsf3ohbeiq2e8vbtf8ik/1593267040000/112894833168181755194/*/1zD3eIL8LCTJ8F_8U3kWA6k5WPJNKr_UZ_93bnARlMxQ?format=tsv' (redirected from 'https://docs.google.com/spreadsheets/d/1zD3eIL8LCTJ8F_8U3kWA6k5WPJNKr_UZ_93bnARlMxQ/export?format=tsv') from origin 'https://viseyes.org' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
Works: www.viseyes.org/scale?1LSnAM3A62AQipZfqxDtlOjt4MWJ0fBP22cdyqJqEj5M
Error: www.viseyes.org/scale?1zD3eIL8LCTJ8F_8U3kWA6k5WPJNKr_UZ_93bnARlMxQ
I believe your goal as follows.
You want to retrieve the data with TSV format from the Google Spreadsheet using Javascript.
Your spreadsheet is publicly shared.
For this, how about this answer?
Issue and workaround:
I could confirm the same situation from your question. Unfortunately, I couldn't remove this error. So, in this case, as a workaround, I would like to propose to use Web Apps created by Google Apps Script as the wrapper. By this, the error can be removed. The flow of this workaround is as follows.
Request to Web Apps from Javascript.
At Web Apps, the data is retrieved from "https://docs.google.com/spreadsheets/d/"+id+"/export?format=tsv".
Return the data with the TSV format from Web Apps.
Usage:
Please do the following flow.
1. Create new project of Google Apps Script.
Sample script of Web Apps is a Google Apps Script. So please create a project of Google Apps Script.
If you want to directly create it, please access to https://script.new/. In this case, if you are not logged in Google, the log in screen is opened. So please log in to Google. By this, the script editor of Google Apps Script is opened.
2. Prepare script.
Please copy and paste the following script (Google Apps Script) to the script editor. This script is for the Web Apps.
function doGet() {
let id = "1zD3eIL8LCTJ8F_8U3kWA6k5WPJNKr_UZ_93bnARlMxQ"; // This is from your script.
let str = "https://docs.google.com/spreadsheets/d/"+id+"/export?format=tsv"; // This is from your script.
const value = UrlFetchApp.fetch(str);
return ContentService.createTextOutput(value.getContentText());
}
If your Google Spreadsheet is not publicly shared, please modify as follows.
function doGet() {
let id = "1zD3eIL8LCTJ8F_8U3kWA6k5WPJNKr_UZ_93bnARlMxQ"; // This is from your script.
let str = "https://docs.google.com/spreadsheets/d/"+id+"/export?format=tsv"; // This is from your script.
const value = UrlFetchApp.fetch(str, {headers: {authorization: "Bearer " + ScriptApp.getOAuthToken()}});
return ContentService.createTextOutput(value.getContentText());
// DriveApp.getFiles() // This is used for automatically detecting the scope.
}
3. Deploy Web Apps.
On the script editor, Open a dialog box by "Publish" -> "Deploy as web app".
Select "Me" for "Execute the app as:".
By this, the script is run as the owner.
Select "Anyone, even anonymous" for "Who has access to the app:".
In this case, no access token is required to be request. I think that I recommend this setting for your goal.
Of course, you can also use the access token. At that time, please set this to "Anyone". And please include the scope of https://www.googleapis.com/auth/drive.readonly and https://www.googleapis.com/auth/drive to the access token. These scopes are required to access to Web Apps.
Click "Deploy" button as new "Project version".
Automatically open a dialog box of "Authorization required".
Click "Review Permissions".
Select own account.
Click "Advanced" at "This app isn't verified".
Click "Go to ### project name ###(unsafe)"
Click "Allow" button.
Click "OK".
Copy the URL of Web Apps. It's like https://script.google.com/macros/s/###/exec.
When you modified the Google Apps Script, please redeploy as new version. By this, the modified script is reflected to Web Apps. Please be careful this.
4. Run the function using Web Apps.
When you use this, please modify your Javascript script as follows and test it.
From:
let id="1zD3eIL8LCTJ8F_8U3kWA6k5WPJNKr_UZ_93bnARlMxQ"
let str="https://docs.google.com/spreadsheets/d/"+id+"/export?format=tsv";
To:
let str = "https://script.google.com/macros/s/###/exec";
Note:
When you modified the script of Web Apps, please redeploy the Web Apps as new version. By this, the latest script is reflected to the Web Apps. Please be careful this.
In my environment, I could confirm that when above workaround is used, no error occurs and the data with the TSV format can be retrieved.
References:
Web Apps
Taking advantage of Web Apps with Google Apps Script

Why does my site cert become insecure after a JQuery AJAX call?

I've got a website that uses JQuery to grab information from an API located at: https://api.lootbox.eu/. The website I'm making has a cert that's been created and installed with Let's Encrypts tools. (I followed a tutorial on DigitalOcean to set it up)
Now, when I click a button to make the API call and update the website contents, Google Chrome then deems the cert "Not Secure" (shown in the address bar).
Here's my code.
//when the page has fully loaded
$(document).ready(function(){
function parseResponse(data)
{
//parsing JSON...
//lets avoid the "data.data"
response = data.data;
//set the user's general profile details
$("#user_avatar").attr("src", response.avatar);
$("#comp_rank_img").attr("src", response.competitive.rank_img);
$("#comp_rank").html(response.competitive.rank);
$("#qp_level").html(response.level);
$("#qp_playtime").html(response.playtime.quick);
$("#comp_playtime").html(response.playtime.competitive);
$("#qp_wins").html(response.games.quick.wins);
$("#comp_total_games").html(response.games.competitive.played);
$("#comp_wins").html(response.games.competitive.wins);
$("#comp_losses").html(response.games.competitive.lost);
}
//goes to the Overwatch API and grabs the JSON data for processing.
function processAjax()
{
$.ajax({
url: "https://api.lootbox.eu/pc/us/JuicyBidet-1292/profile"
}).then( function(response){
parseResponse(response);
});
}
//set up the button event listener
$("#submit").click(function(e){
//prevent the button from reloading the page
e.preventDefault();
//run the ajax grabber/processor
processAjax();
});
});
(I need to learn how to format code properly in SO questions...).
I don't get any other errors in my Chrome console (other than "favicon" 404ing - which is unrelated).
I've also tried the website in Microsoft Edge and I get the following in their Console:
SCRIPT7002: XMLHttpRequest: Network Error 0x800c0019, Security certificate required to access this resource is invalid.
I'm thinking either the problem is with my code, or now that I've checked, the API website's cert is invalid in both Chrome and Edge.
Any help would be appreciated. Thanks.
(I'm aware the code is scrappy, I'm learning)
I get this warning "This server could not prove that it is api.lootbox.eu; its security certificate expired 6 days ago"
This could happen because of one among following reasons.
1.Certificate is not issued by the third party site.
2.The third party site certificate is not updated.
3.The third party and browser connection is not secure.
The insecure error is because if a site is loaded over https the browser expects all subsequent calls made by the page will be secure, but in your case you are calling a URL http://api.lootbox.eu/pc/us/JuicyBidet-1292/profile which uses http:// and is insecure thus making your website insecure.
Solution
Use https url's everywhere in your pages.

How to remotely fetch answer of phantomjs script run on heroku?

I want to fetch some information from a website using the phantomjs/casperjs libraries, as I'm looking for the HTML result after all javascripts on a site are run. I worked it out with the following code from this answer:
var page = require('webpage').create();
page.open('http://www.scorespro.com/basketball/', function (status) {
if (status !== 'success') {
console.log('Unable to access network');
} else {
var p = page.evaluate(function () {
return document.getElementsByTagName('html')[0].innerHTML
});
console.log(p);
}
phantom.exit();
});
And I also worked it out to get phantomjs/casperjs running on heroku by following these instructions, so when I now say heroku run phantomjs theScriptAbove.js on OS X terminal I get the HTML of the given basketball scores website as I was expecting.
But what I actually want is to get the html text from within a Mac desktop application, this is the reason why I was looking for a way to run the scripts on a web server like heroku. So, my question is:
Is there any way to get the HTML text (that my script prints as a result) remotely within my Objective-C desktop application?
Or asked in another way: how can I run and get the answer of my script remotely by using POST/GET?
p.s.
I can handle with Rails applications, so if there's a way to do this using Rails - I just need the basic idea of what I have to do and how to get the phantomjs script to communicate with Rails. But I think there might be an even simpler solution ...
If I understand you correctly you're talking about interprocess communication - so that Phantom's result (the page HTML) can somehow be retrieved by the app.
per the phantom docs, couple options:
write the HTML to a file and pick up the file in your app
run the webserver module and do a GET to phantom, and have the phantom script respond with the page HTML
see http://phantomjs.org/api/webserver/

Sending msg and post on own wall function no longer work

I created social feeds functions(sending msg to friends and posting on own wall) using javascript SDK and graph API in Facebook 2-3 months ago for my apps. It was working perfectly when I created but now, when I visit my app and try to use them again, it no longer works. It's so strange since I never touched that code after I implemented them. I even tried to copy and pasting exact sample javascript code given in Facebook document and it didn't work either. Even after I re-write my code, it still doesn't work either. I have no idea what is wrong. Anyone face similar problem with javascript SDK? Thanks in advance.
Hi,
The code is here: Sorry for late reply.
<script src='http://connect.facebook.net/en_US/all.js'></script>
<script>
FB.init({
appId : 'id',
status : true, // check login status
cookie : true, // enable cookies to allow the server to access the session
xfbml : true // parse XFBML
});
</script>
<script>
function share_wall() {
// calling the API ...
var obj = {
method: 'feed',
link: 'https://apps.facebook.com/id/',
name: 'test',
description: 'blalala'
};
FB.ui(obj);
}
</script>
I realized I actually have the same problem as you =\ Go to your app settings and make the additional configuration under Basic Settings.
If your domain is http://inspiration.nyp.edu.sg
If you are working on localhost
"Symptoms"
Previously, your JavaScript SDK functions were working fine. Now, executing your JavaScript SDK functions prompts you either an API Error Code 191 or an error.
Your PHP SDK functions are working fine.
Your JavaScript SDK functions work fine when you run your application as App on Facebook, but does not when you run your application as a Page Tab.
(For my case, the last date I checked was 7 August 2012 and my JavaScript SDK functions were working fine. It was until 3 September 2012 when I checked them again, then I encountered the errors mentioned above.)
I highly recommend everyone to check their Page Tab application's JavaScript SDK functions such as feed dialog, apprequests and etc.

Categories