【问题标题】:Client-side retrieval of Google Contact pictures谷歌联系人图片的客户端检索
【发布时间】:2014-02-09 20:54:54
【问题描述】:

我正在使用 Google JavaScript API 在 web 应用中获取 google 联系人,并且我想检索他们的图片。

我正在做这样的事情(高度简化):

var token; // let's admit this is available already

function getPhotoUrl(entry, cb) {
  var link = entry.link.filter(function(link) {
    return link.type.indexOf("image") === 0;
  }).shift();
  if (!link)
    return cb(null);
  var request = new XMLHttpRequest();
  request.open("GET", link.href + "?v=3.0&access_token=" + token, true);
  request.responseType = "blob";
  request.onload = cb;
  request.send();
}

function onContactsLoad(responseText) {
  var data = JSON.parse(responseText);
  (data.feed.entry || []).forEach(function(entry) {
    getPhotoUrl(e, function(a, b, c) {
      console.log("pic", a, b, c);
    });
  });
}

但是我在 Chrome 和 Firefox 中都遇到了这个错误:

跨源请求被阻止:同源策略不允许读取位于https://www.google.com/m8/feeds/photos/media/<user_email>/?v=3.0&access_token= 的远程资源。这可以通过将资源移动到同一域或启用 CORS 来解决。

当查看来自 feeds/photos 端点的响应标头时,我可以看到 Access-Control-Allow-Origin: * 没有发送,因此我得到了 CORS 错误。

请注意,到达feeds/contacts 端点时会发送Access-Control-Allow-Origin: *,因此允许跨域请求。

这是一个错误,还是我错过了他们文档中的某些内容?

【问题讨论】:

    标签: oauth google-oauth gdata-api google-data-api google-shared-contacts


    【解决方案1】:

    假设您只需要“个人资料图片”,请尝试通过将完整 URL 设置为 &lt;img&gt; 标记的 src 元素(带有 ?access_token=&lt;youknowit&gt; 在结束)。

    例如使用 Angular.js

    <img ng-src="{{contact.link[1].href + tokenForImages}}" alt="photo" />
    

    一般来说,对于 CORS,似乎有不少地方从 JS 访问 API 没有按预期工作。

    希望这会有所帮助。

    【讨论】:

      【解决方案2】:

      还不能评论,所以这个答案……

      显然您已经在Google developers console 中设置了正确的客户端 ID 和 JavaScript 来源。

      domain shared contacts API 似乎不像宣传的那样工作,并且仅在您请求 JSONP 数据时遵守其 CORS 承诺(您的代码表明您使用 JSON 获取条目数据)。对于 JSON 格式,API 将 access-control-allow-origin 设置为 * 而不是您为项目列出的 JavaScript 来源。

      但是从今天(2015-06-16)开始,如果您尝试使用不同的数据类型(例如 atom/xml)发出 GETPOST...,Google API 将不会完全设置 access-control-allow-origin,因此您的浏览器将拒绝您访问数据的请求(错误 405)。

      这显然是一个错误,它阻止了对共享联系人 API 的任何编程使用,但对于条目的简单列表:不能再创建、更新、删除条目或访问照片。

      如果我弄错了,请纠正我(我希望是这样);如果您知道向 Google 提交此错误的最佳方式,请发表评论或编辑。

      注意,为了完整起见,这里是我用来访问联系人的代码框架(需要 jQuery)。

          <button id="authorize-button" style="visibility: hidden">Authorize</button>
          <script type="text/javascript">
              var clientId = 'TAKE-THIS-FROM-CONSOLE.apps.googleusercontent.com',
                  apiKey = 'TAKE-THAT-FROM-GOOGLE-DEVELOPPERS-CONSOLE',
                  scopes = 'https://www.google.com/m8/feeds';
              // Use a button to handle authentication the first time.
              function handleClientLoad () {
                  gapi.client.setApiKey ( apiKey );
                  window.setTimeout ( checkAuth, 1 );
              }
              function checkAuth() {
                  gapi.auth.authorize({client_id: clientId, scope: scopes, immediate: true}, handleAuthResult);
              }
              function handleAuthResult ( authResult ) {
                  var authorizeButton = document.getElementById ( 'authorize-button' );
                  if ( authResult && !authResult.error ) {
                      authorizeButton.style.visibility = 'hidden';
                      var cif = {
                          method: 'GET',
                          url:  'https://www.google.com/m8/feeds/contacts/mydomain.com/full/',
                          data: {
                              "access_token": authResult.access_token,
                              "alt":          "json",
                              "max-results":  "10"
                          },
                          headers: { 
                              "Gdata-Version":    "3.0"    
                          },
                          xhrFields: {
                              withCredentials: true
                          },
                          dataType: "jsonp"
                      };
                      $.ajax ( cif ).done ( function ( result ) {
                              $ ( '#gcontacts' ).html ( JSON.stringify ( result, null, 3 ) );
                      } );
                  } else {
                      authorizeButton.style.visibility = '';
                      authorizeButton.onclick = handleAuthClick;
                  }
              }
              function handleAuthClick ( event ) {
                  gapi.auth.authorize ( { client_id: clientId, scope: scopes, immediate: false }, handleAuthResult );
                  return false;
              }
          </script>
          <script src="https://apis.google.com/js/client.js?onload=handleClientLoad"></script>
          <pre id="gcontacts"></pre>
      

      如果将 cif.data.alt 替换为 atom 和/或 cif.dataType 替换为 xml,则会收到臭名昭著的错误 405。

      ps:cif 当然与ajax 相关;-)

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-08-03
        • 1970-01-01
        • 1970-01-01
        • 2013-11-03
        • 1970-01-01
        • 2012-08-26
        相关资源
        最近更新 更多