Клиентский поиск картинок Google Contact
Я выбираю контакты Google в веб-приложении с помощью Google JavaScript API и хочу получить их фотографии.
Я делаю что-то вроде этого (сильно упрощено):
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/%3Cuser_email
/ ? V =3.0&access_token= , Это можно исправить, переместив ресурс в тот же домен или включив CORS.
Просматривая заголовки ответов с конечной точки каналов / фотографий, я вижу, что Access-Control-Allow-Origin: *
не отправлено, следовательно, ошибка CORS я получаю.
Обратите внимание, что Access-Control-Allow-Origin: *
отправляется при достижении feeds/contacts
конечная точка, следовательно, разрешает междоменные запросы.
Это ошибка, или я что-то упустил из их документов?
2 ответа
Пока не могу комментировать, поэтому этот ответ...
Очевидно, вы уже настроили правильный идентификатор клиента и происхождение JavaScript в консоли разработчиков Google.
Похоже, что API общих контактов домена не работает так, как рекламируется, и выполняет только обещание CORS, когда вы запрашиваете JSONP
данные (ваш код указывает, что вы получили свои входные данные, используя JSON). Для формата JSON API устанавливает access-control-allow-origin
* вместо источников JavaScript, перечисленных вами для вашего проекта.
Но по состоянию на сегодня (2015-06-16), если вы попытаетесь выдать GET
, POST
... с другим типом данных (например, atom
/xml
), 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.
Предполагая, что вам нужна только "картинка профиля", попробуйте переместить запрос этого изображения непосредственно в HTML, указав полный URL-адрес в качестве src
элемент <img>
тег (с ?access_token=<youknowit>
в конце).
Например, используя Angular.js
<img ng-src="{{contact.link[1].href + tokenForImages}}" alt="photo" />
Что касается CORS в целом, кажется, что существует довольно много мест, где доступ к API из JS не работает должным образом.
Надеюсь это поможет.