С Cordova трудно работать. Особенно когда используешь с ней сторонние web-сервисы. Так и теперь, типичный парсер использующий Google Spreadsheet занял у меня почти 2 недели. Обо всём этом по-порядку. В 1or2 решили хранить и модифицировать клиентские данные в одной совместной таблице на Spreadsheet. Об этом я писал ещё в предыдущей новости. Короче, сделать выгрузку в CSV легко не получилось, поэтому заюзал Apps Script. С ним можно взаимодействовать со многими Google сервисами по REST-API. Получилось вот так (наработки по выгрузке CSV сохранил здесь). Apps Script, в целом, мне не понравился. Такая древняя технология, основанная на EcmaScript 3, с простеньким веб-редактором, дебаггером, версионностью и легкой интеграцией с консолью Google. Правильные шаги получения результата из Apps Script такие: 1. Загрузить gapi либу; 2. Показать окно с авторизацией; 3. Ввести логин+пароль и получить токен; 4. Исполтзовать токен для доступа к данным. Успешно оттестировав на браузере при портировании под Cordova получил ошибку: Refused to display... бла-бла-бла ...in a frame because it set 'X-Frame-Options' to 'SAMEORIGIN'.Его листинг приложил ниже: function googleOAuth(CLIENT_ID, SCOPES) { return new Promise((resolve, reject) => { if (!window.cordova) { window.gapi.auth.authorize({ client_id: CLIENT_ID, scope: SCOPES, response_type: 'token', immediate: false }, (authResult) => { resolve(authResult); }); } else { if (window.cordova.InAppBrowser) { const redirect_uri = 'http://localhost/callback'; const browserRef = window.cordova.InAppBrowser.open( `https://accounts.google.com/o/oauth2/auth?client_id=${CLIENT_ID}` + `&redirect_uri=${redirect_uri}` + `&scope=${SCOPES.join(' ')}` + '&approval_prompt=force' + '&response_type=token id_token', '_blank', 'location=no,clearsessioncache=yes,clearcache=yes' ); browserRef.addEventListener('loadstart', (event) => { if ((event.url).indexOf(redirect_uri) === 0) { browserRef.removeEventListener('exit', () => { }); browserRef.close(); let callbackResponse = (event.url).split('#')[1]; let responseParameters = (callbackResponse).split('&'); let parameterMap = []; for (let i = 0; i < responseParameters.length; i++) { parameterMap[responseParameters[i].split('=')[0]] = responseParameters[i].split('=')[1]; } if (parameterMap.access_token !== undefined && parameterMap.access_token !== null) { resolve({ access_token: parameterMap.access_token, expires_in: parameterMap.expires_in, id_token: parameterMap.id_token, token_type: parameterMap.token_type }); } else { reject('Problem authenticating'); } } }); browserRef.addEventListener('exit', () => { reject('The sign in flow was canceled'); }); } else { reject('Could not find InAppBrowser plugin'); } } }); } Залив очередной билд на девайс получил уже другую ошибку. Теперь попросту не открывалось окно авторизации. Приложение ругалось на запросы через file:/// Пофиксил это установив плагин InAppBrowser. Далее окно авторизации уже стало работать. Но с ошибкой. Не нравился мой callback-запрос. В консоле убрал последний слэш в запросе http://localhost/callback Далее приложение ругалось на невозможность выполнения запросов. Пофиксил это, установив плагин whitelist и добавил в config.xml следующее содержимое: <allow-navigation href="https://ssl.gstatic.com/*" /> <allow-navigation href="https://apis.google.com/*" /> <allow-navigation href="https://*.googleusercontent.com/*" /> <allow-navigation href="https://accounts.google.com/*" /> <allow-navigation href="https://www.googleapis.com/*" /> <allow-navigation href="https://*.googleapis.com/*" /> <allow-intent href="*" /> <allow-intent href="https://*.googleapis.com/*" /> <allow-intent href="https://apis.google.com/*" /> На всякий случай добавил вот такую мету в index.html: <meta http-equiv="Content-Security-Policy" content="default-src ; img-src 'self' data: blob: filesystem:; script-src 'self' 'unsafe-inline' 'unsafe-eval' ; style-src 'self' 'unsafe-inline' *"> Короче говоря, пока занимался такой вот тривиальной задачей так устал, что думал вообще останавливать запил игрули. Но спустя две недели я получил необходимый массив значений на девайсе. Но вот, честно сказать, никакой радости от этого я уже не испытываю. Либу cordova-google-oauth2 выложил с лицензией MIT. |
Новости >