No se pueden recibir datos POST a menos que actualice el cliente. ¿Por qué? ¿Cómo puedo esperar a que se reciban los datos de la publicación antes de que se cargue la página?

Alex Smith

Mi aplicación comienza con un formulario html simple. las entradas son el número de PIN y la fecha de nacimiento.

Mi servidor express se ejecuta en el mismo puerto 3000, cuando el usuario envía sus datos, titiritero se inicia e inicia sesión en una página web específica. Luego raspo la imagen en esa página web. Google Api toma el texto de esa imagen y lo guarda en una matriz. Luego publico esa cadena de matriz en src / results.html. Pero tan pronto como el usuario presiona enviar, se le redirige a / resuelve la ruta inmediatamente y la página dice que no se pueden publicar los datos. pero cuando veo en la consola (aproximadamente un minuto después) que la publicación fue exitosa, actualizo la página y obtengo la matriz de texto que quería ver.

¿Cómo puedo esperar a que los datos terminen de publicarse en la ruta antes de que la página cargue los datos? Estoy usando Reaccionar para el lado del cliente. A continuación se muestra el código del lado del servidor. El lado del cliente es solo un inicio de sesión básico de la página de reacción y una página estática / de resultados destinada a los datos.

const puppeteer = require("puppeteer");
const express = require("express");
const app = express();
const morgan = require("morgan");
const fs = require("fs");
const cors = require("cors");
const request = require("request-promise-native").defaults({ Jar: true });
const poll = require("promise-poller").default;

app.use(morgan("combined"));
const port = 3000;
// Imports the Google Cloud client library
const vision = require("@google-cloud/vision");
require("dotenv").config();

app.use(cors());

const textArray = [];

const App = (pinNum, dateOfB) => {
  const config = {
    sitekey: process.env.SITEKEY,
    pageurl: process.env.PAGEURL,
    apiKey: process.env.APIKEY,
    apiSubmitUrl: "http://2captcha.com/in.php",
    apiRetrieveUrl: "http://2captcha.com/res.php",
  };

  const chromeOptions = {
    executablePath: "/Program Files/Google/Chrome/Application/chrome.exe",
    headless: true,
    slowMo: 60,
    defaultViewport: null,
  };

  async function main() {
    const browser = await puppeteer.launch(chromeOptions);
    const page = await browser.newPage();

    console.log(`Navigating to ${config.pageurl}`);
    await page.goto(config.pageurl);
    try {
      const requestId = await initiateCaptchaRequest(config.apiKey);

      // const pin = getPIN();
      console.log(`Typing PIN ${pinNum}`);
      await page.type("#PIN", pinNum);

      // const dob = getDOB();
      console.log(`Typing DOB ${dateOfB}`);
      const input = await page.$("#DOB");
      await input.click({ clickCount: 3 });
      await input.type(dateOfB);

      const response = await pollForRequestResults(config.apiKey, requestId);

      console.log(`Entering recaptcha response ${response}`);
      await page.evaluate(
        `document.getElementById("g-recaptcha-response").innerHTML="${response}";`
      );

      console.log(`Submitting....`);
      page.click("#Submit");
    } catch (error) {
      console.log(
        "Your request could not be completed at this time, please check your pin number and date of birth.  Also make sure your internet connection is working and try again."
      );
      console.error(error);
    }

    await page.waitForSelector(
      "body > div.container.body-content > div:nth-child(1) > div:nth-child(2) > p"
    );
    const image = await page.$(
      "body > div.container.body-content > div:nth-child(1) > div:nth-child(2) > p"
    );
    await image.screenshot({
      path: "testResults.png",
    });

    await getImageText();
    await page.close(); // Close the website
    await browser.close(); //close browser
    await deleteImage();
  }
  main();

  //This section grabs the text off the image that was gathered from the web scraper.

  async function getImageText() {
    // Creates a client
    const client = new vision.ImageAnnotatorClient();
    console.log(`Looking for text in image`);
    // Performs label detection on the image file
    const [result] = await client.textDetection("./testResults.png");
    const [annotation] = result.textAnnotations;
    const text = annotation ? annotation.description : "";
    console.log("Extracted text from image:", text);

    //Pushed the text into a globally available array.
    textArray.push(text);

    //Sent a NOTIFICATION ALERT to the client with the text gathered from the image.
    var axios = require("axios");
    var data = JSON.stringify({
      to: "dp8vGNkcYKb-k-72j7t4Mo:APA91bEfrI3_ht89t5X1f3_Y_DACZc9DbWI4VzcYehaQoXtD_IHIFSwm9H1hgXHNq46BQwDTlCKzkWNAHbBGauEXZNQtvhQc8glz4sHQr3JY3KM7OkUEcNB7qMMpCPxRe5GzzHbe3rkE",
      notification: {
        body: text,
        title: "AverHealth Schedule",
      },
    });

    var config = {
      method: "post",
      url: "https://fcm.googleapis.com/fcm/send",
      headers: {
        "Content-Type": "application/json",
        Authorization: `key=${process.env.FCM_SERVER_KEY}`,
      },
      data: data,
    };

    axios(config)
      .then(function (response) {
        console.log(JSON.stringify(response.data));
      })
      .catch(function (error) {
        console.log(error);
      });

    
   
  }

  //Captcha Solver for the web scraper
  async function initiateCaptchaRequest(apiKey) {
    const formData = {
      key: apiKey,
      method: "userrecaptcha",
      googlekey: config.sitekey,
      json: 1,
      pageurl: config.pageurl,
    };

    console.log(
      `Submitting recaptcha request to 2captcha for ${config.pageurl}`
    );
    const response = await request.post(config.apiSubmitUrl, {
      form: formData,
    });
    console.log(response);
    return JSON.parse(response).request;
  }

  async function pollForRequestResults(
    key,
    id,
    retries = 90,
    interval = 5000,
    delay = 1500
  ) {
    console.log(`Waiting for ${delay} milliseconds....`);
    await timeout(delay);
    return poll({
      taskFn: requestCaptchaResults(key, id),
      interval,
      retries,
    });
  }

  function requestCaptchaResults(apiKey, requestId) {
    const url = `${config.apiRetrieveUrl}?key=${apiKey}&action=get&id=${requestId}&json=1`;
    console.log(url);
    return async function () {
      return new Promise(async function (resolve, reject) {
        console.log(`Polling for response...`);
        const rawResponse = await request.get(url);
        console.log(rawResponse);
        const resp = JSON.parse(rawResponse);
        console.log(resp);
        if (resp.status === 0) return reject(resp.request);
        console.log("Response received");
        console.log(resp);
        resolve(resp.request);
      });
    };
  }

  // DELETES THE FILE CREATED BY GOOGLEAPI
  function deleteImage() {
    const path = "./testResults.png";
    try {
      fs.unlinkSync(path);
      console.log("File removed:", path);
    } catch (err) {
      console.error(err);
    }
  }

  const timeout = (ms) => new Promise((res) => setTimeout(res, ms));
};

app.use(express.urlencoded({ extended: false }));

// Route to results Page
app.get("/results", (req, res) => {
  res.sendFile(__dirname + "/src/results.html");
  res.send(textArray);
});

app.post("/results", (req, res) => {
  // Insert Login Code Here
  let username = req.body.username;
  let password = req.body.password;
  App(username, password);
});

app.listen(port, () => {
  console.log(`Scraper app listening at http://localhost:${port}`);
});

Rishabh Gupta

Creo que tengo el problema.

En la reactaplicación, tal vez no esté usando e.preventDefault()cuando hace clic en enviar. El navegador, de forma predeterminada, redirige a una página a la que dirige la acción del formulario, si el atributo de acción está vacío, el navegador vuelve a cargar la misma página. Le recomendaría que lo use e.preventDefault()en el envío de formularios y luego use la fetchAPI para realizar la solicitud.

En el expressservidor, en la ruta POST "resultados", no está enviando ninguna respuesta al usuario. Siempre debe enviar una respuesta al usuario. En su caso, está llamando a la Appfunción, que tiene muchas funciones asíncronas, pero no está esperando App()que se complete en la ruta POST, express envía una respuesta predeterminada al usuario tan pronto como analiza App(), no está esperando a App()que se complete - Express llegará a esto más tarde.

Puede hacer que la (req, res) => { ... }función en la ruta sea una asyncfunción async (req, res) => { ... }, luego también puede hacer la Appfunción asincrónica. Entonces puedes await App(...)en la función de ruta. Además, debe esperar la main()función también dentro de la App()función. Luego, una vez App()finalizada la llamada, puede enviar una respuesta de redireccionamiento al usuario.

Este artículo se recopila de Internet, indique la fuente cuando se vuelva a imprimir.

En caso de infracción, por favor [email protected] Eliminar

Editado en
0

Déjame decir algunas palabras

0Comentarios
Iniciar sesiónRevisión de participación posterior

Artículos relacionados

TOP Lista

CalienteEtiquetas

Archivo