我已经在 React+Vite 环境中成功复制了 Google Calendar API,但是在引入 Django 时它根本不起作用。有什么具体原因吗?如果是这样,我很乐意解释原因。
import React, { useState, useEffect } from 'react'
function App() {
const CLIENT_ID = myid;
const API_KEY = mykey;
const DISCOVERY_DOC = 'https://www.googleapis.com/discovery/v1/apis/calendar/v3/rest';
const SCOPES = "https://www.googleapis.com/auth/calendar";
const accessToken = localStorage.getItem('access_token');
console.log(accessToken)
const expiresIn = localStorage.getItem('expires_in');
console.log(expiresIn)
let gapiInited = false, gisInited = false, tokenClient;
useEffect(() => {
gapiLoaded()
gisLoaded()
}, [])
function gapiLoaded() {
gapi.load('client', initializeGapiClient);
}
async function initializeGapiClient() {
await gapi.client.init({
apiKey: API_KEY,
discoveryDocs: [DISCOVERY_DOC],
});
gapiInited = true;
console.log("GAPI #1 INITIATED")
if (accessToken && expiresIn) {
gapi.client.setToken({
access_token: accessToken,
expires_in: expiresIn,
});
listUpcomingEvents();
}
}
function gisLoaded() {
tokenClient = google.accounts.oauth2.initTokenClient({
client_id: CLIENT_ID,
scope: SCOPES,
callback: '', // Defined Later
});
console.log("Success")
gisInited = true;
}
//Enables user interaction after all libraries are loaded.
// I believe the error happens here, it never console.logs GAPI 2
function handleAuthClick() {
console.log("GAPI 1")
tokenClient.callback = async (resp) => {
console.log("GAPI 2")
if (resp.error) {
throw (resp);
}
console.log("GAPI 3")
// await listUpcomingEvents();
console.log("GAPI 4")
const { access_token, expires_in } = gapi.client.getToken();
localStorage.setItem('access_token', access_token);
localStorage.setItem('expires_in', expires_in)
console.log("GAPI 5")
window.location.reload()
};
if (!(accessToken && expiresIn)) {
// Prompt the user to select a Google Account and ask for consent to share their data
// when establishing a new session.
tokenClient.requestAccessToken({ prompt: 'consent' });
} else {
// Skip display of account chooser and consent dialog for an existing session.
tokenClient.requestAccessToken({ prompt: '' });
}
}
//Sign out the user upon button click.
function handleSignoutClick() {
const token = gapi.client.getToken();
if (token !== null) {
google.accounts.oauth2.revoke(token.access_token);
gapi.client.setToken('');
localStorage.clear();
window.location.reload();
}
}
async function listUpcomingEvents() {
let response;
try {
const request = {
'calendarId': 'primary',
'timeMin': (new Date()).toISOString(),
'showDeleted': false,
'singleEvents': true,
'maxResults': 10,
'orderBy': 'startTime',
};
response = await gapi.client.calendar.events.list(request);
} catch (err) {
document.getElementById('content').innerText = err.message;
return;
}
const events = response.result.items;
if (!events || events.length === 0) {
document.getElementById('content').innerText = 'No events found.';
return;
}
// Flatten to string to display
const output = events.reduce(
(str, event) => `${str}${event.summary} (${event.start.dateTime || event.start.date})\n`,'Events:\n');
document.getElementById('content').innerText = output;
}
function addManualEvent(){
var event = {
'kind': 'calendar#event',
'summary': 'Volunteer Here',
'location': 'Chicago, IL',
'description': 'Clean up litter.',
'start': {
'dateTime': '2023-05-18T01:05:00.000Z',
'timeZone': 'UTC'
},
'end': {
'dateTime': '2023-05-18T01:35:00.000Z',
'timeZone': 'UTC'
},
'recurrence': [
'RRULE:FREQ=DAILY;COUNT=1'
],
'attendees': [
{'email': '','responseStatus':'needsAction'},
],
'reminders': {
'useDefault': true,
},
"guestsCanSeeOtherGuests": true,
}
var request = gapi.client.calendar.events.insert({'calendarId': 'primary','resource': event,'sendUpdates': 'all'});
request.execute((event)=>{
console.log(event)
window.open(event.htmlLink)
window.location.reload()
},(error)=>{
console.error(error);
});
}
return (
<div>
<button id="authorize_button" hidden={accessToken && expiresIn} onClick={handleAuthClick}>Sign Into Calendar</button>
<button id="signout_button" hidden={!accessToken && !expiresIn} onClick={handleSignoutClick}>Sign Out</button>
<button id='add_manual_event' hidden={!accessToken && !expiresIn} onClick={addManualEvent}>Add Event</button>
<pre id="content" style={{ whiteSpace: 'pre-wrap' }}></pre>
</div>
)
}
export default App
此代码在 React+Vite 环境中有效,但在引入 Django 时无效。
我调试了每个代码块,我相信 handleAuthClick() 是问题的根源。
我的脚本标签已正确加载到 index.html 中