Любая идея о том, как обрабатывать Safari, отправляя несколько запросов GET, когда ожидается только один? - PullRequest
0 голосов
/ 19 июня 2019

Во время тестирования моего приложения узла в Safari маршруты, которые хранятся в истории моего браузера, по-видимому, дважды проверяются на запрос и выполняют все вызовы методов, связанные с этим путем, дважды (сам браузер, кажется, получает только один ответ хотя).

Это в первую очередь проблема, потому что я взаимодействую с API Календаря Google, чтобы добавить новое событие календаря - сейчас тестовое событие добавляется дважды, когда я пытаюсь добавить его один раз. Пока что это происходит только в Safari (но я тестировал только в Safari и Chrome).

Что на самом деле происходит:

Я начинаю набирать «localhost: 3000 / add», браузер предсказывает последние две буквы пути, и как только появляется прогнозирующий текст, я вижу через console.log, что приложение выполняет путь, определенный в приложении .get ('/ add'), даже если ни одно из этих действий не видно на стороне браузера (например, браузер не обновляет и не отображает информацию, полученную от вызова API, даже если эта информация регистрируется, и отправка информации в res является частью той же функции, вызывающей операторы журнала).

Затем, когда я действительно ввожу адрес, путь выполняется снова, но на этот раз браузер обновляется при получении ответа и отображает новые данные.

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 происходит двойное событие при посещении самой страницы календаря.

(Кроме того, я довольно незнаком с использованием разметки, поэтому, если форматирование для части кода этого вопроса не удается, я заранее извиняюсь, и, пожалуйста, не стесняйтесь игнорировать сообщение, пока я не смогу его исправить)

1 Ответ

0 голосов
/ 24 июня 2019

Эта проблема действительно вызвана тем, что Safari автоматически загружает предложенные URL-адреса. Согласно одному из комментариев Криспи в этом обсуждении , веб-стандарт просто не выполняет действия в результате запроса GET, а вместо этого использует POST, PUT или DELETE, поскольку ни один из этих типов запросы приводят к предварительной загрузке.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...