在Safari上测试我的节点应用程序时,存储在浏览器历史记录中的路由似乎每个请求都会被ping通两次,并执行两次与该路径相关的所有方法调用(浏览器本身似乎仅收到一个响应,但)。
这主要是一个问题,因为我正在与Google Calendar API进行接口以添加新的日历事件-现在,当我尝试将其添加一次时,测试事件将被添加两次。到目前为止,这似乎仅在Safari中发生(但我仅在Safari和Chrome中进行过测试)。
实际发生的事情:
我开始输入“ localhost:3000 / add”,浏览器会预测路径的最后两个字母,并且当预测文本出现时,我就可以通过console.log看到应用程序执行了在应用程序中定义的路径.get('/ add'),即使该活动在浏览器端都不明显(例如,即使正在记录该信息,浏览器也不会刷新并显示从API调用接收到的信息,并且向res发送信息是导致log语句的同一功能的一部分。
然后,当我实际输入地址时,路径会再次执行,但是这次浏览器在收到响应后刷新,并显示新数据。
test.js:
"use strict";
const express = require('express');
const app = express();
//must be initialized with .init()
const CalendarManager = require('./GoogleCalApi.js');
const calendar = new CalendarManager();
require('dotenv').config('./.env');
calendar.init(process.env.GOOGLE_CLIENT_ID,
process.env.GOOGLE_CLIENT_SECRET,
process.env.REDIRECT_URL + '/oauthcallback',
(m) => console.log);
app.get('/', (req, res) => {
res.sendFile(process.cwd() + '/views/test.html')
})
app.get('/verify', (req, res) => {
calendar.getAuthUrl((err, url)=>{ err ? res.send('error getting auth url') :
res.redirect(url) });
})
app.get('/oauthcallback', (req, res) => {
console.log('callback ping')
let done = (err, message) => message ? res.send(message) : res.send(err);
calendar.storeCred(req.query.code, done)
})
app.get('/add', (req, res) => {
console.log('add route ping')
let event = {
'summary': 'TestEvent',
'start': {
'date': '2019-07-13'
},
'end': {
'date': '2019-07-14'
}
}
calendar.addEvent(event, (err, data) => { res.send(err ? err : data) });
})
app.listen(3000, () => {console.log('listening on port 3000')})
GoogleCalApi.js:
const {google} = require('googleapis');
function GoogleCalendarApi () {
this.initialized = false;
this.oauth2Client = null;
this.url = null;
this.token = null;
this.calendar = null;
this.init = function (clientId, clientSecret, redirect_url, done) {
this.oauth2Client = new google.auth.OAuth2(
clientId,
clientSecret,
redirect_url
);
this.scopes = ['https://www.googleapis.com/auth/calendar'];
this.url = this.oauth2Client.generateAuthUrl({
access_type: 'offline',
scope: this.scopes
})
//listeners
this.oauth2Client.on('tokens', (tokens) => {
console.log('token event:', this.token)
if (tokens.refresh_token) {
this.token = tokens.refresh_token;
console.log('refresh: ' + tokens.refresh_token)
}
console.log('auth token: ' + tokens.access_token)
})
console.log('initialized', this.oauth2Client)
this.initialized = true;
done('initialized');
};
/**
* @param done: callback function that can handle two params: error and url
* -error should be null, or an error message
* -url should be an address for Google Cloud's authentication process
**/
this.getAuthUrl = (done) => { this.url ? done(null, this.url) : done('error: url not defined') }
this.storeCred = function (code, done) { //code from req.query.code
async function cred (auth) {
try {
console.log('storeCred ping')
const {tokens} = await auth.getToken(code)
auth.setCredentials(tokens)
console.log('tokens', tokens)
done(null, 'authenticated')
} catch (err) {
console.log('error in cred:', err)
done(err)
}
}
try { cred(this.oauth2Client) } catch (err) { done(err) }
}
this.addEvent = function (event, done) {
console.log('add event ping')
if (this.calendar === null) this.calendar = google.calendar({version: 'v3', auth: this.oauth2Client});
this.calendar.events.insert({
auth: this.oauth2Client,
calendarId: 'primary',
resource: event
}, (err, data) => { done(null, data) })
}
} //end constructor
module.exports = GoogleCalendarApi;
如上所述,我看到了:
add route ping
add event ping
add route ping
add event ping
在控制台中,当我只能看到以下内容时:
add route ping
add event ping
当我访问日历页面本身时,我要更新的Google日历发生重复事件。
(而且,我对使用markdown不太熟悉,因此,如果该问题的代码部分格式化失败,我会提前道歉,请随时忽略该帖子,直到能够解决该问题为止)< / p>
答案 0 :(得分:0)
此问题确实是由Safari自动预载建议的网址引起的。根据{{3}}中krispy的评论之一,Web标准只是不执行作为GET请求的结果的操作,而是使用POST,PUT或DELETE作为替代,因为这些类型的请求都不会导致预加载。