Google Fusion Table API v1-正确组成的REST格式可发布更新 [英] Google Fusion Table API v1 - Properly composed REST format to POST an UPDATE

查看:71
本文介绍了Google Fusion Table API v1-正确组成的REST格式可发布更新的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

您好,互联网人, 我正在努力通过Javascript对Google Fusion Table进行更新...这是一个博客,但我想我应该将其全部写在一个地方,而不是零碎的问题(所有这些都是相互关联的-相关).

我可以轻松地从Fusion Tables中进行SELECT,还可以通过oauth(更多的工作)来检索Auth令牌,因此通过RowID和字段名称将是可行的.

对于google-api-javascript-client有许多相当不错的帖子和示例,但是,las,在阅读并阅读了许多这些帖子之后,我还没有能够成功地进行组合和推断以使其适用于我的预期目的:

-我希望允许网页用户通过javascript对我的Fusion Table中的现有记录(使用Fusion Tables作为数据库)进行简单更新,而不必依赖任何服务器端PHP或用于oauth等的Java.

关于上述问题的问题:仅通过javascript尝试这样做是否合理?或者我应该放弃客户端"策略?...而是开发服务器端架构(用于处理Fusion Tables)作为数据库).

通过javascript进行更新的一些特定问题: A.)UPDATE是否在REST调用上需要API密钥?

B.)...还是REST调用仅需要Auth Token?

C.)...还是API密钥和Auth令牌?

D.)UPDATE是否需要& callback ="?在REST通话上?

E.)GWT oauth javascript库是否可以( http://code.google.com /p/gwt-oauth2/)与javascript-api-client库( https://code.google.com/p/google-api-javascript-client/)?还是混合了苹果和橘子?

F.)也许仅使用jQuery库来构成和格式化用于执行UPDATE的对融合表的纯REST调用?标题字符串和POST方法将如何包含在url字符串中?.. auth Token有什么用?如何进行回叫?

F.1)google-api-javascript-client的"gapi.client.request"方法具有用于提交REST调用的结构...我想这就是该库存在的原因:但是如何/在何处"gapi.client.request"明确包含auth令牌?...是否应该成为URL字符串的一部分?

这是通过gapi.client.request推送以进行REST调用的URL的示例...实际的tableID当然在字符串中,当然下面的访问令牌已经过期...但基本的SQL是: UPDATE TABLEID SET STATUS STATUS COMPLETE WHERE ROWID 2

https://www.googleapis.com/fusiontables/v1/query?sql = UPDATE%20 TABLEID%20SET%20STATUS%20%3D%20COMPLETED%20WHERE%20ROWID%20%3D%20'2'& access_token = ya29.AHES6ZSCxJu4V0kOXN98H3PBKJon6ynewZ4jI4w9iFs3IOs

上面的代码看起来应该可以正常工作并更新表,但是dang darn heck则不行.

这是我的测试代码,由于我尝试了数十种组合,因此有点混乱:

请注意,我也正在努力处理回调...因为它也无法正常工作,是的,也许,如果我能看到回调,则可以更好地解决这种情况(我觉得我必须相当接近解决方案,因此不想立即放弃并退回到PHP服务器端)...因此,对回调的任何帮助也将不胜感激.

非常感谢您可能提供的任何帮助/见解.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<%@ Page Language="C#" %>
<html dir="ltr" xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Untitled 1</title>
<script type="text/javascript" src="gwt-oauth2.js"></script>
<script src="https://apis.google.com/js/client.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
</head>
<body>

<form id="form1" runat="server">
  <div data-role="fieldcontain" id="div-myButton1" >
     <p></p>
        <input type="button" id="myButton1" value="oAuth & Get Token" />
     <p></p>
   </div>

 <p id="myOutput"><i>token goes here 3...</i></p>

<div data-role="fieldcontain" id="div-myButton2" >
     <p></p>
        <input type="button" id="myButton2" value="Attempt Fusion Table Update" />
     <p></p>
</div>

<p id="myOutput2"><i>transmitted POST url here...</i></p>

<p id="insert-data-output"><i>Fusion table callback status here...</i></p>

<script type="text/javascript">
$( "#myButton1" ).click(function() {
 //Using the GWT oauth2 javascript library to get the Auth token
 //...as was not able to explicitly retrieve token using the google-api-javascript 
 //alert("got here");
 var GOOGLE_AUTH_URL = "https://accounts.google.com/o/oauth2/auth";
//my client ID
var GOOGLE_CLIENT_ID = "YOURID.apps.googleusercontent.com";
var PLUS_ME_SCOPE = "https://www.googleapis.com/auth/plus.me";
//
var req = {
     "authUrl" : GOOGLE_AUTH_URL,
     "clientId" : GOOGLE_CLIENT_ID,
     //"scopes" : [ PLUS_ME_SCOPE ],
     "scopes" : ['https://www.googleapis.com/auth/fusiontables'],
   };
   oauth2.login(req, function(token) {
     //alert("Got an OAuth token:\n" + token + "\n"
     //    + "Token expires in " + oauth2.expiresIn(req) + " ms\n");
     //
     myOutput.innerText = token;
     //
   }, function(error) {
     alert("Error:\n" + error);
   });
 });
 </script>  

 <script type="text/javascript">
 $( "#myButton2" ).click(function() {
 //Attempting to update a Fusion Table record using gapi, google-api-javascript
 //...as was not able to update using the GWT javascript library
 //
 //TBD???: Where does the auth Token go when composing the REST update string?...tac on to the end?
 //??does UPDATE also require the API key?...if so where in the string?
 //
 //alert("got here");
 //myOutput2.innerText = "got here";
 //
 //my Fusion Table: TABLEID
 var query = "UPDATE TABLEID SET STATUS = COMPLETED WHERE ROWID = '2'";
 var encodedQuery = encodeURIComponent(query);
 // Construct the URL
 //the push seems to be putting in extra commas! :-(
 //var url = ['https://www.googleapis.com/fusiontables/v1/query'];
 var url = 'https://www.googleapis.com/fusiontables/v1/query';
 //url.push('?sql=' + encodedQuery);
 url = url + '?sql=' + encodedQuery;
 //my API key
 //url.push('&key=YOURAPIKEY');
 //Is the API Key required?
 //&access_token=
 //another choice might be to drop the API key, and put in the access token
 //url.push('&access_token=');
  myAccessTokenIs = '&access_token=' + myOutput.innerText;
  //url.push(myAccessTokenIs);
  url = url + myAccessTokenIs;
  //maybe drop the call back stuff too???
  //url.push('&callback=?');
  //
  //alert("my url is: " + url);
  myOutput2.innerText = url;
  //
  var path = '/fusiontables/v1/query';
  //
  //used for the callback of the gapi.client.request
  var callback = function(what) {
  alert("got to call back??");
  var output = JSON.stringify(what);
  insert-data-output.innerText = output;
  };
  ////var callback = function(element) {
  //    return function(resp) {
  //    var output = JSON.stringify(resp);
  //    document.getElementById(element).innerHTML = output;
  //};
  // 
  gapi.client.request({
    path:path,
    body: url,
    headers: {'Content-Type': 'application/x-www-form-urlencoded'},
    method:'POST'},
   callback
   );
  });
 </script>  

 <script>
  function helloCallBack(callback) {
   //callback('insert-data-output');
 };
 </script>
 </form>
 </body>
 </html>

解决方案

我尝试回答您的所有问题:

  • 请参见 JavaScript API示例,以查看客户端的使用情况.您需要所有请求的API密钥以及client_id和OAuth范围来授权用户.
  • 您想要的不是完全可能的:如果您想要一个仅客户端解决方案,您所能做的就是要求用户使用其帐户进行身份验证(如上面的示例).但是,如果要访问共享的一个特定表,则必须具有某种服务器端代码.
  • 我首先开始使用JSONP API(按照您的建议,使用jQuery创建调用),但随后切换到gapi-client.它更容易,它可以为您提供有意义的错误消息,并且我可以毫无问题地访问我的数据.

我有非常相似的要求:尽可能使用客户端代码,访问属于我的Google帐户的单个表(使用FT作为数据库).关键是使用所谓的服务帐户.您可以使用服务帐户在服务器上执行此操作,而不是要求用户进行授权:

  1. 创建帐户
  2. 在表格上为服务帐户设置权限
  3. 授权帐户(获取访问令牌)
  4. 提出授权请求

现在您有2个选择:

  • 通过您的服务器将所有请求路由到融合表(添加访问令牌)

OR

  • 将获取的令牌交给客户端,并处理来自客户端的所有请求

第二个选项很危险,因为这意味着服务帐户是公开的,因此您必须仔细检查您对该帐户授予的权限(即,如果您不注意,则可以删除记录),但请注意通过这种方式,您可以将服务器端代码的数量减少到最少.

在我的应用程序中,选择第二个选项.但是为了限制我创建的帐户作为表的读视图和写视图的可能性.并且服务帐户只能访问这两个视图.在读取视图上,该帐户具有查看者"权限,因此可以读取整个表( SELECT 语句).在写视图中,它具有编辑器"权限,这使得可以 INSERT / UPDATE / Delete (尽管 DROP 是不可能的.)

我个人没有使用GWT库,但是我看不出为什么它不起作用的原因.我使用 PHP OAuth库.包含我的代码的存储库是公共的,对您来说有趣的部分可能是我的服务器辅助代码(用于获取服务帐户到客户端的访问令牌的JSONP接口).

我想我回答了您所有的问题,如果我留下了什么,请随时提出澄清.

Hello kind people of the internet, I'm struggling to make an UPDATE to a Google Fusion Table occur via Javascript...and this is a bit of blog, but thought I'd just write it all up in one place rather than piece meal questions (that are all inter-related).

I'm able to do SELECT from Fusion Tables (easy) and I'm also able to retrieve the Auth Token via oauth (bit more work), so it would seem reasonable that an UPDATE of a field value by RowID and field name would be doable.

There are a number of fairly good posts and examples for the google-api-javascript-client, but alas, after reading and reading many of these posts, I have not successfully been able to combine and extrapolate to make them work for my intended purpose:

-I would like users of a web page to be allowed to make a simple update, via javascript, of an already existing record in my Fusion Table (use Fusion Tables as a database), without relying on any server side PHP or Java for the oauth, etc.

Question on the above point: Is this a reasonable thing to attempt via javascript alone?...or should I just abandon the 'client' side strategy?...and instead develop a server side architecture (for handling Fusion Tables as a db).

Some specific Questions for the UPDATE via javascript: A.) Does the UPDATE require the API key on the REST call?

B.)...or does the REST call require just the Auth Token?

C.)...or both the API key and Auth token?

D.) Does the UPDATE require the "&callback=?" on the REST call?

E.) Can the GWT oauth javascript library ( http://code.google.com/p/gwt-oauth2/ ) be combined with the javascript-api-client library ( https://code.google.com/p/google-api-javascript-client/ )? Or is this mixing apples and oranges?

F.) How perhaps would a pure REST call to fusion tables for doing an UPDATE be composed and formatted using just the jQuery library? How would the headers and the POST method be included in the url string?..what about the auth Token?, and how would the call back be done?

F.1) The "gapi.client.request" method of the google-api-javascript-client has a structure for submitting the REST call...I suppose that's why the library exists: but how/where does the "gapi.client.request" explicitly include the auth token?...is it suppose to be part of the URL string?

Here's an example of the URL that is being pushed through the gapi.client.request for the REST call...the real tableID is of course in the string, and of course the access token below has already expired...but the basic SQL is: UPDATE TABLEID SET STATUS COMPLETED WHERE ROWID 2

https://www.googleapis.com/fusiontables/v1/query?sql=UPDATE%20 TABLEID %20SET%20STATUS%20%3D%20COMPLETED%20WHERE%20ROWID%20%3D%20'2'&access_token=ya29.AHES6ZSCxJu4V0kOXN98H3PBKJon6ynewZ4jI4w9iFs3IOs7

The above looks like it should basically work and update the table, but dang darn heck, does not.

Here's my testing code, and it's a bit messy as I've tried many dozens of combinations:

Note that I'm also struggling with the callback...as it's not working (yet) either, and yes, perhaps if I could see the call back I could better troubleshoot the situation (I feel that I must be fairly close to a solution, so don't want to give up just yet and fall back to PHP server side)...so any help on the callback would be much appreciated too.

thanks much in advance for any help/insight you might be able to provide.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<%@ Page Language="C#" %>
<html dir="ltr" xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Untitled 1</title>
<script type="text/javascript" src="gwt-oauth2.js"></script>
<script src="https://apis.google.com/js/client.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
</head>
<body>

<form id="form1" runat="server">
  <div data-role="fieldcontain" id="div-myButton1" >
     <p></p>
        <input type="button" id="myButton1" value="oAuth & Get Token" />
     <p></p>
   </div>

 <p id="myOutput"><i>token goes here 3...</i></p>

<div data-role="fieldcontain" id="div-myButton2" >
     <p></p>
        <input type="button" id="myButton2" value="Attempt Fusion Table Update" />
     <p></p>
</div>

<p id="myOutput2"><i>transmitted POST url here...</i></p>

<p id="insert-data-output"><i>Fusion table callback status here...</i></p>

<script type="text/javascript">
$( "#myButton1" ).click(function() {
 //Using the GWT oauth2 javascript library to get the Auth token
 //...as was not able to explicitly retrieve token using the google-api-javascript 
 //alert("got here");
 var GOOGLE_AUTH_URL = "https://accounts.google.com/o/oauth2/auth";
//my client ID
var GOOGLE_CLIENT_ID = "YOURID.apps.googleusercontent.com";
var PLUS_ME_SCOPE = "https://www.googleapis.com/auth/plus.me";
//
var req = {
     "authUrl" : GOOGLE_AUTH_URL,
     "clientId" : GOOGLE_CLIENT_ID,
     //"scopes" : [ PLUS_ME_SCOPE ],
     "scopes" : ['https://www.googleapis.com/auth/fusiontables'],
   };
   oauth2.login(req, function(token) {
     //alert("Got an OAuth token:\n" + token + "\n"
     //    + "Token expires in " + oauth2.expiresIn(req) + " ms\n");
     //
     myOutput.innerText = token;
     //
   }, function(error) {
     alert("Error:\n" + error);
   });
 });
 </script>  

 <script type="text/javascript">
 $( "#myButton2" ).click(function() {
 //Attempting to update a Fusion Table record using gapi, google-api-javascript
 //...as was not able to update using the GWT javascript library
 //
 //TBD???: Where does the auth Token go when composing the REST update string?...tac on to the end?
 //??does UPDATE also require the API key?...if so where in the string?
 //
 //alert("got here");
 //myOutput2.innerText = "got here";
 //
 //my Fusion Table: TABLEID
 var query = "UPDATE TABLEID SET STATUS = COMPLETED WHERE ROWID = '2'";
 var encodedQuery = encodeURIComponent(query);
 // Construct the URL
 //the push seems to be putting in extra commas! :-(
 //var url = ['https://www.googleapis.com/fusiontables/v1/query'];
 var url = 'https://www.googleapis.com/fusiontables/v1/query';
 //url.push('?sql=' + encodedQuery);
 url = url + '?sql=' + encodedQuery;
 //my API key
 //url.push('&key=YOURAPIKEY');
 //Is the API Key required?
 //&access_token=
 //another choice might be to drop the API key, and put in the access token
 //url.push('&access_token=');
  myAccessTokenIs = '&access_token=' + myOutput.innerText;
  //url.push(myAccessTokenIs);
  url = url + myAccessTokenIs;
  //maybe drop the call back stuff too???
  //url.push('&callback=?');
  //
  //alert("my url is: " + url);
  myOutput2.innerText = url;
  //
  var path = '/fusiontables/v1/query';
  //
  //used for the callback of the gapi.client.request
  var callback = function(what) {
  alert("got to call back??");
  var output = JSON.stringify(what);
  insert-data-output.innerText = output;
  };
  ////var callback = function(element) {
  //    return function(resp) {
  //    var output = JSON.stringify(resp);
  //    document.getElementById(element).innerHTML = output;
  //};
  // 
  gapi.client.request({
    path:path,
    body: url,
    headers: {'Content-Type': 'application/x-www-form-urlencoded'},
    method:'POST'},
   callback
   );
  });
 </script>  

 <script>
  function helloCallBack(callback) {
   //callback('insert-data-output');
 };
 </script>
 </form>
 </body>
 </html>

解决方案

I try to answer all your questions:

  • See the JavaScript API example to see the usage of the gapi-client. You need the API key for all requests and the client_id and the OAuth scope to authorize a user.
  • What you want is not exactly possible: if you want a client-side only solution, all you can do is ask a user to authenticate with their account (like the example above). But if you want to access one specific table that you share, you have to have some kind of server-side code.
  • I started using the JSONP API first (creating calls with jQuery, like you suggested), but then switched to the gapi-client. It's easier, it can give you meaningful error messages and I had no problem to access my data.

I had very similar requirements: use client-side code as much as possible, access a single table that belongs to my Google-Account (using FT as database). The key is to use a so called Service Account. Instead of asking the user to authorize, you do this on the server with the Service Account:

  1. Create the account
  2. Set permission on the table for the Service Account
  3. Authorize the account (aquire the access token)
  4. Make authorized requests

Now you have 2 options:

  • Route all request to the fusion table via your server (adding the access token)

OR

  • Give the acquired token to the client side, and handle all request from there

The second option is dangerous, because this means that the Service Account is public, so you have to check carefully which permissions you give to this account (i.e. it's possible to delete records if you don't pay attention), but aside from that you reduce the amount of server-side code to a minimum.

In my application I choose this second option. But to limit the possibilities of the account I created as read-view and a write-view of my table. And the Service Account only got access to those two views. On the read-view the account has "Viewer" permission and can therefore read the whole table (SELECT statements). On the write-view it has "Editor"-permission, which makes it possible to INSERT / UPDATE / DELETE (although DROP is not possible).

I personally didn't use the GWT library, but I can't see a reason why this should not work. I did the server-side call with the PHP OAuth library. The repository with my code is public, the interesting part for you might be my JavaScript library for FT (GftLib) and the server side code (JSONP interface to get the access token of the Service Account to the client).

I think I answered all of your questions, if I left something, feel free to ask for clarification.

这篇关于Google Fusion Table API v1-正确组成的REST格式可发布更新的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆