You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

无需访客认证,在网站展示个人Google Calendar的技术咨询

问题:无需访客认证展示个人Google Calendar日程

我想在个人网站展示自己的Google Calendar日程,让他人查看我的可用时间。目前实现的方案需要访客完成Google认证,但我仅需读取自己的日历数据用于展示,完全不需要访问他人的日历。我已在Google Cloud Console配置了API Key、Client ID,但现有方案均要求访客完成账号认证;也试过iframe嵌入方式,但希望获取日历数据后自定义样式。当前的JS和HTML代码会触发访客认证流程(代码如下),寻求无需访客认证即可展示自身日历的可行方法。


现有代码

JS代码

function gapiLoaded() {
    gapi.load('client', initializeGapiClient);
}

async function initializeGapiClient() {
    try {
        await gapi.client.init({
            apiKey: API_KEY,
            discoveryDocs: ["https://www.googleapis.com/discovery/v1/apis/calendar/v3/rest"],
        });
        gisLoaded();
    } catch (error) {
        console.error('Error initializing Google Calendar API client:', error);
       
    }
}

function gisLoaded() {
    const tokenClient = google.accounts.oauth2.initTokenClient({
        client_id: CLIENT_ID,
        scope: 'https://www.googleapis.com/auth/calendar.readonly',
        callback: handleAuthResponse,
    });
    tokenClient.requestAccessToken();
}

function handleAuthResponse(response) {
    if (response.error) {
        console.error('Error authenticating:', response);
        
        return;
    }
    loadCalendarEvents();
}

async function loadCalendarEvents() {
    try {
        const response = await gapi.client.calendar.events.list({
            'calendarId': CALENDAR_ID,
            'timeMin': (new Date()).toISOString(),
            'showDeleted': false,
            'singleEvents': true,
            'maxResults': 10,
            'orderBy': 'startTime'
        });

        const events = response.result.items;
        const calendarDiv = document.getElementById('calendar');
        calendarDiv.innerHTML = ''; // Clear loading message

        events.forEach(event => {
            const eventDiv = document.createElement('div');
            eventDiv.className = 'event';

            const titleDiv = document.createElement('div');
            titleDiv.className = 'event-title';
            titleDiv.textContent = event.summary;
            eventDiv.appendChild(titleDiv);

            const timeDiv = document.createElement('div');
            timeDiv.className = 'event-time';
            const start = event.start.dateTime || event.start.date;
            timeDiv.textContent = new Date(start).toLocaleString();
            eventDiv.appendChild(timeDiv);

            calendarDiv.appendChild(eventDiv);
        });
    } catch (error) {
        console.error('Error fetching calendar events:', error);
        
    }
}

window.onload = function() {
    console.log('window.onload: Page fully loaded');
    
    gapiLoaded();
};

HTML代码

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>St. Patrick's Irish Pub - Menu</title>
    <link rel="stylesheet" href="calendar.css">
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0-beta3/css/all.min.css">
    <script src="https://accounts.google.com/gsi/client" async defer></script>
    <script src="https://apis.google.com/js/api.js"></script>
</head>
<body>
    <div class="calendar" id="calendar"></div>
    <script src="calendar2.js"></script>
</body>
</html>

可行解决方案

方法1:将日历设为公开,用API Key直接访问

这是最简单的前端实现方式,适合可以公开日程的场景:

  1. 配置日历公开权限
    • 打开你的Google Calendar,找到目标日历,点击「设置和共享」
    • 在「访问权限设置」中,开启「对所有人可见」,权限选择「查看日程详情」
  2. 修改前端代码,移除OAuth认证流程
    直接用fetch调用Calendar API,无需访客认证:
const API_KEY = '你的API_KEY';
const CALENDAR_ID = '你的日历ID';

async function loadCalendarEvents() {
    try {
        // 直接调用Calendar API,用API Key授权
        const response = await fetch(`https://www.googleapis.com/calendar/v3/calendars/${CALENDAR_ID}/events?timeMin=${(new Date()).toISOString()}&showDeleted=false&singleEvents=true&maxResults=10&orderBy=startTime&key=${API_KEY}`);
        
        if (!response.ok) {
            throw new Error(`API请求失败: ${response.status}`);
        }
        
        const data = await response.json();
        const events = data.items;
        const calendarDiv = document.getElementById('calendar');
        calendarDiv.innerHTML = '';

        events.forEach(event => {
            const eventDiv = document.createElement('div');
            eventDiv.className = 'event';

            const titleDiv = document.createElement('div');
            titleDiv.className = 'event-title';
            titleDiv.textContent = event.summary || '无标题';
            eventDiv.appendChild(titleDiv);

            const timeDiv = document.createElement('div');
            timeDiv.className = 'event-time';
            const start = event.start.dateTime || event.start.date;
            timeDiv.textContent = new Date(start).toLocaleString();
            eventDiv.appendChild(timeDiv);

            calendarDiv.appendChild(eventDiv);
        });
    } catch (error) {
        console.error('获取日历事件失败:', error);
        document.getElementById('calendar').textContent = '加载日程失败,请稍后重试';
    }
}

window.onload = loadCalendarEvents;

修改后的HTML(移除OAuth相关脚本):

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>我的可用日程</title>
    <link rel="stylesheet" href="calendar.css">
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0-beta3/css/all.min.css">
</head>
<body>
    <div class="calendar" id="calendar">加载中...</div>
    <script src="calendar2.js"></script>
</body>
</html>

注意事项:

  • 公开日历意味着任何人都能通过日历ID和API Key访问,请勿在该日历中添加敏感内容
  • 在Google Cloud Console的API Key设置里,限制API Key的使用范围为「Google Calendar API」,并添加网站Referrer限制,防止API Key被滥用

方法2:后端代理(适合不想完全公开日历的场景)

如果不想把日历设为公开,可以通过后端服务账号获取数据,前端仅请求自己的后端接口:

  1. 在Google Cloud Console创建服务账号,下载JSON密钥文件
  2. 在Google Calendar的共享设置中,添加服务账号邮箱,授予「查看日程详情」权限
  3. 后端用服务账号调用Calendar API获取数据,提供一个接口给前端
  4. 前端直接请求自己的后端接口,无需任何认证

这种方法更安全,日历不会公开,API密钥也不会暴露在前端。


内容的提问来源于stack exchange,提问作者Kripthonite

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.21 07:22:41