4

我正在使用Google JavaScript API獲取web應用程序中的谷歌聯繫人,我想檢索它們的圖片。谷歌聯繫人圖片的客戶端檢索

我在做這樣的事情(很大程度上簡化):

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這樣的錯誤:

跨來源請求阻止:相同Origin Policy不允許讀取遠程資源https://www.google.com/m8/feeds/photos/media/<user_email>/< some_contact_id>?v = 3.0 & access_token = < obfuscated>。這可以通過將資源移動到相同的域或啓用CORS來解決。

當查看來自feeds/photos端點的響應標頭時,我可以看到Access-Control-Allow-Origin: *未發送,因此我得到CORS錯誤。

請注意,Access-Control-Allow-Origin: *在到達feeds/contacts端點時發送,因此允許跨域請求。

這是一個錯誤,還是我錯過了他們的文檔中的東西?

回答

1

假設您只需要「個人資料圖片」,請嘗試將該圖片的請求直接轉換爲HTML格式,方法是將完整網址設置爲<img>標記的src元素(末尾爲?access_token=<youknowit>)。

E.g.使用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數據(你的代碼表明您使用JSON了您的輸入數據)的CORS承諾。對於JSON格式,API將access-control-allow-origin設置爲*,而不是您爲項目列出的JavaScript源。

但今天(2015年6月16日),如果你嘗試發出GETPOST ...用不同的數據類型(例如​​/xml),谷歌的API將不設置訪問控制,允許-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> 

如果通過xml通過​​和/或cif.dataType更換cif.data.alt,你得到了臭名昭著的錯誤405

PS:cif固然與ajax ;-)