3

I'm trying to use ContentService, to serve JSONP in a webpage with Google Apps Script, following the samples provided in this link under "Serving JSONP in Web Pages" sub-topic.

GS code:

function doGet(request) {
  var events = CalendarApp.getEvents(
    new Date(Number(request.parameters.start) * 1000),
    new Date(Number(request.parameters.end) * 1000));
  var result = {
    available: events.length == 0
  };
  return ContentService.createTextOutput(
    request.parameters.prefix + '(' + JSON.stringify(result) + ')')
    .setMimeType(ContentService.MimeType.JSON);
}

HTML/JS Code:

<script src="https://script.google.com/macros/s/AKfycbwZCY0qrZ09szGvKOttA30IaJkdMAZrh_oNnvv0qzCqFWyuO5Wc/exec?start=1325437200&end=1325439000&prefix=alert"></script>


I published it, by deploying the GS code as webapp, with the following parameters:

  • Executing the app as: User accessing the web app
  • Who has access to the app: Anyone

Unfortunately, whenever I try to run/open the HTML file containing the code, I got the following error in browser's console, and nothing happens:

enter image description here

How to run this sample provided in Google Apps Script link without errors ?




[OPTIONAL] Investigating the issue in details:

The error found in resources files generate by the browser is as follows: enter image description here

And the browser translated DOM is as follows:

<html>
   <head>
       <script src="https://script.google.com/macros/s/AKfycbwZCY0qrZ09szGvKOttA30IaJkdMAZrh_oNnvv0qzCqFWyuO5Wc/exec?start=1325437200&amp;end=1325439000&amp;prefix=alert">
       </script>
   </head>
   <body></body>
</html>

The generated link, in my case is:
"https://script.google.com/macros/s/AKfycbwZCY0qrZ09szGvKOttA30IaJkdMAZrh_oNnvv0qzCqFWyuO5Wc/exec?start=1325437200&end=1325439000&prefix=alert"

If this link is placed in browser address bar, it shows the following message: enter image description here

which means that the returned authorization response wasn't able to be displayed on browser and being translated as valid DOM.

How to overcome this issue ?

4

4 回答 4

6

JSONP 需要以下任何一项才能工作:

  1. 匿名访问,“用户访问 webapp”模式不可用 - 您需要以“像我一样执行”运行它。
  2. 不使用任何需要授权的服务的脚本,在这种情况下,您可以选择“用户访问 webapp”。这仅适用于登录到 Google 的用户,与以前的模式相比,使用它的唯一优势是所用服务的任何配额都将应用于每个用户,而不是应用于 webapp 的所有用户。一般来说,更喜欢选项1。
  3. 已被用户预授权的脚本。这也仅适用于登录用户,但它可以让您使用任何服务。请参阅下文了解如何使用它。

我假设您正在尝试使用 3 - 否则,使用 1 它将正常工作。如果您确实需要 3 个(例如,访问用户电子邮件的 JSONP 服务),您将必须让他们能够在服务运行之前对其进行授权。为此,请在 doGet() 中添加如下内容:

function doGet(e) {
  if (e.parameter.auth) 
    return HtmlService.createHtmlOutput('Thank you! Now the script can run!');
  // ... rest of your code
}

然后,您可以为用户提供他们可以访问的 script.google.com/YOUR_SCRIPT_URL?auth=1 的链接。(值 1 无关紧要......任何值都可以)。他们将获得授权页面,如果他们接受授权,他们将看到您的感谢消息,并且 JSONP 服务将为他们工作。只需执行一次...脚本将在用户下次访问您的页面时记住授权,除非您已将其更改为需要新权限或用户已撤销授权。

于 2012-12-26T15:56:13.047 回答
1

在任何网页中提供 JSONP 总是会引发错误:

未捕获的 SyntaxError:意外的标识符

这可能会得到纠正,但在意料之中,因为它将数据发送到 GAS 环境(UiApp 或 HTMLservice)之外的外部页面。如果您在客户端创建自己的 javascript 函数,ServiceContent 运行良好。

Apps 脚本代码:

function doGet(e) {
   // ..more code
   lReturn = true;
   var mymessage = (lReturn==true) ? "your contact details are saved ! ":" data no saved.. ";
   var result = { status: lReturn, message : mymessage };
   return ContentService.createTextOutput(
     e.parameter.prefix + '(' + JSON.stringify(result) + ')')
    .setMimeType(ContentService.MimeType.JSON);`
  }

和 Javascript 代码(使用 JQuery):

var url = <your Apps Script URL>?prefix=myabc
$.ajax({
  type: "GET",
  url: url1,
  data: {callback:"?"},
  dataType: "script"
  }).done( function( data ) {
         console.log(data); //data returned : UNDEFINED
});

和你自己的javascript函数:

function myabc(data) {
  //alert(data);
  //alert(data.message);
  //var xyz = JSON.stringify(data);
  //alert(xyz);
  alert(data.message);
}

最好的问候
@Mlaynes http://mlaynessanchez.blogspot.com

于 2013-03-13T21:17:26.177 回答
1

问题是您尝试在客户端代码中执行的 jsonp“脚本”不是有效的 Javascript,如您所示,它是授权 html 网页。授权后应该没问题。不过,正如教程所说,在部署网络应用程序时,您可以以自己(“我”)的身份执行该应用程序,然后允许访问“任何人,甚至匿名”,并且您不会收到任何授权提示。尽管在查看您的日历和用户的日历方面,这显然有一些不同的行为。Corey G 提供了一种很好的方式来提示授权。

于 2012-12-26T17:39:07.650 回答
0

对于 ajax 调用,您必须在服务器端使用 setMimeType (ContentService.MimeType.JAVASCRIPT);

于 2017-05-05T16:15:35.130 回答