5

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 >/<some_contact_id>?v=3.0&access_token=<obfuscated>のリモート リソースの読み取りが禁止されています. これは、リソースを同じドメインに移動するか、CORS を有効にすることで修正できます。

フィード/写真エンドポイントからの応答ヘッダーを見ると、Access-Control-Allow-Origin: *送信されていないことがわかり、CORS エラーが発生します。

Access-Control-Allow-Origin: *はエンドポイントに到達したときに送信されるfeeds/contactsため、クロスドメイン リクエストが許可されることに注意してください。

これはバグですか、それとも彼らのドキュメントから何かを見逃していましたか?

4

2 に答える 2

2

まだコメントできないため、この回答は…</p>

もちろん、Google 開発者コンソールで適切なクライアント ID と JavaScript オリジンを設定済みです。

ドメイン共有の連絡先 API は宣伝どおりに機能せず、データを要求するときに CORS の約束に従うだけのようですJSONP(コードは、JSON を使用してエントリ データを取得したことを示しています)。JSON 形式の場合、API は、access-control-allow-originプロジェクト用にリストした JavaScript オリジンの代わりに * に設定します。

しかし、今日 (2015-06-16) の時点で、異なるデータ型 (例: / ) でGET, …を発行しようとすると、Google API は access-control-allow-origin をまったく設定しないため、ブラウザデータへのアクセス要求を拒否します (エラー 405)。POSTatomxml

これは明らかにバグであり、共有連絡先 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と、悪名高いエラー 405 が発生します。atomcif.dataTypexml

ps: cifはもちろんajaxに関連しています;-)

于 2015-06-16T07:17:54.950 に答える