我正在开发一个网络应用程序,您可以在其中从您的 Google 帐户查看日历,这是我当前的代码。
我的日历位于主页 (
index.html
) 内的 iframe 内,按下按钮时会激活
当我从
index.html
按下在 iframe 中加载 Google 日历的按钮时,我在控制台中两次收到此错误: 登录 Google 时出错:错误:Google API 尚未正确加载。
在 showGoogleCalendar (calendar2/:119:12)
在 HTMLButtonElement.onclick (calendar2/:245:62)
显示日历Google @ calendar2/:145
onclick @calendar2/:245 在这些行中:
日历2/:145 (是 showGoogleCalendar() 函数)
日历2/:178 (是handleError()函数)
在谷歌云平台上,我启用了 Google Calendar API,我有我的 api 密钥、我的 OAuth 2.0 客户端 ID 和配置的重定向 URL。
编辑:由于暮光的评论,我解决了这个问题
现在我有这个代码:
<script>
let config;
async function loadConfig() {
const response = await fetch('./keys/google.json');
config = await response.json();
gapi.load('client', initializeGapiClient);
}
async function initializeGapiClient() {
// Mostrar una animación de carga mientras se carga el calendario de Google
Swal.fire({
title: 'Cargando Calendario de Google...',
allowOutsideClick: false,
didOpen: () => {
Swal.showLoading();
}
});
try {
await gapi.client.init({
apiKey: config.api_key,
discoveryDocs: [config.discovery_doc],
});
fetchEvents();
} catch (error) {
console.error('Error initializing Google API client', error);
Swal.fire({
icon: 'error',
title: 'Error',
text: 'Ocurrió un error al cargar el calendario de Google. Por favor, inténtalo de nuevo más tarde.'
});
} finally {
// Cerrar la animación de carga una vez inicializado el cliente de Google API
Swal.close();
}
}
async function fetchEvents() {
const token = localStorage.getItem('googleAccessToken');
if (token) {
gapi.client.setToken({ access_token: token });
try {
const response = await gapi.client.calendar.events.list({
'calendarId': 'primary',
'timeMin': '2020-01-01T00:00:00Z', // Fecha y hora mínima para obtener eventos
'showDeleted': false,
'singleEvents': true,
'maxResults': 10,
'orderBy': 'startTime',
});
let events = response.result.items.map(event => ({
title: event.summary,
start: event.start.dateTime || event.start.date,
end: event.end.dateTime || event.end.date,
}));
// Verificar si hay más eventos disponibles y recuperarlos
let nextPageToken = response.result.nextPageToken;
while (nextPageToken) {
const additionalResponse = await gapi.client.calendar.events.list({
'calendarId': 'primary',
'timeMin': '2020-01-01T00:00:00Z',
'showDeleted': false,
'singleEvents': true,
'maxResults': 10,
'orderBy': 'startTime',
'pageToken': nextPageToken,
});
events = events.concat(additionalResponse.result.items.map(event => ({
title: event.summary,
start: event.start.dateTime || event.start.date,
end: event.end.dateTime || event.end.date,
})));
nextPageToken = additionalResponse.result.nextPageToken;
}
renderCalendar(events);
Swal.close();
} catch (err) {
console.error('Error fetching events', err);
Swal.fire({
icon: 'error',
title: 'Error al cargar eventos',
text: 'Ocurrió un error al intentar cargar los eventos. Por favor, inténtalo de nuevo más tarde.'
});
Swal.close();
}
} else {
console.error('No se encontró ningún token de acceso');
Swal.fire({
icon: 'error',
title: 'No se encontró token de acceso',
text: 'No se encontró ningún token de acceso. Por favor, inicia sesión nuevamente.'
});
Swal.close();
}
}
function renderCalendar(events) {
const calendarEl = document.getElementById('calendar');
const calendar = new FullCalendar.Calendar(calendarEl, {
customButtons: {
myCustomButton: {
text: '🔄 Refrescar',
click: function () {
Swal.fire({
title: 'Actualizando eventos...',
allowOutsideClick: false,
didOpen: () => {
Swal.showLoading();
fetchEvents();
},
});
},
},
logout: {
text: '❌ Cerrar Sesión',
click: () => {
console.log('Cerrando sesion Google...');
Swal.fire({
title: 'Cerrando sesión...',
allowOutsideClick: false,
didOpen: () => {
Swal.showLoading();
},
});
try {
localStorage.removeItem('googleAccessToken');
localStorage.setItem('logoutCompletedG', 'true');
console.log('Sesion Google cerrada correctamente');
Swal.close();
window.location.href = 'local.html';
} catch (error) {
Swal.close();
Swal.fire({
icon: 'error',
title: 'Error al cerrar sesión',
text: 'Ocurrió un error al intentar cerrar sesión. Por favor, inténtalo de nuevo más tarde.'
});
console.log('Error al cerrar sesion Google');
}
}
}
},
headerToolbar: {
left: 'prev,next today myCustomButton logout',
center: 'title',
right: 'dayGridMonth,timeGridWeek,timeGridDay'
},
buttonText: {
today: 'Hoy',
month: 'Mes',
week: 'Semana',
day: 'Día',
list: 'Lista'
},
initialView: 'dayGridMonth',
locale: 'es',
firstDay: 1,
events: events,
dayMaxEvents: true,
eventClick: function (info) {
const event = info.event;
const title = event.title;
const start = event.start;
const end = event.end;
const allDay = event.allDay;
const location = event.extendedProps.location;
const timeZone = Intl.DateTimeFormat().resolvedOptions().timeZone;
const startFormatted = start.toLocaleString('es-ES', { timeZone: timeZone });
const endFormatted = end ? end.toLocaleString('es-ES', { timeZone: timeZone }) : 'Evento de todo el día';
let content = `<h2>${title}</h2>`;
if (!allDay) {
content += `<p><strong>Inicio:</strong> ${startFormatted}</p>`;
content += `<p><strong>Fin:</strong> ${endFormatted}</p>`;
} else {
content += `<p><strong>Evento de todo el día</strong></p>`;
}
if (location) {
content += `<p><strong>Ubicación:</strong> ${location}</p>`;
}
Swal.fire({
title: 'Información del Evento',
html: content,
icon: 'info'
});
}
});
calendar.render();
}
loadConfig();
</script>
我现在遇到的问题有两个非常明确,有没有办法即使在刷新网站或关闭浏览器时也能保持使用Google帐户登录会话?第二个问题,为了生成日历,我使用 fullcalendar 库,并且在加载事件的函数中,当我想要加载事件时,我必须专门放置,是否有一个选项可以使其更加动态?例如,如果我回到几个月前,它会逐年加载吗?
非常感谢!!
根据我在评论部分的建议,将其发布为答案:
该问题已通过必要的双重检查得到解决
Google API dependencies and scopes
。另外,参考这个 Javascript Quickstart(Calendar API).