2
votes

La connexion socket.io renvoie un tableau vide. Comment recevoir des données dans React sans recharger la page?

Je crée une extension chrome dans React. J'essaye de télécharger des données via socket.io. Je n'ai reçu aucune erreur, mais le tableau est vide.

Je devrais définir l'en-tête et le jeton, mais je ne sais pas où le faire dans le serveur app.js . Où puis-je définir:

import socketIOClient from "socket.io-client";

class App extends Component {
  constructor (props) {
    super(props);
    this.state = {
      scores: []
      endpoint: "http://127.0.0.1:4001" /How endpoint in `chrome extension`?
    }
  }

componentDidMount() {
  const { endpoint } = this.state;
  const token = "12345"; 

  const socket = socketIOClient(endpoint);

  socket.on("FromAPI", data => this.setState({ todos: data }));
}


  render () {
      <div>
      </div>
    )
  }
}

export default App;

Comment puis-je définir port dans le serveur app.js code > et endpoint dans le client app.jsx si je crée une extension chrome ?

Y a-t-il un autre moyen (autre que socket.io ) pour recevoir des données dans la méthode componentDidMount () dans React sans recharger la page?

Quand je vais à l'adresse http: / /127.0.0.1:4001 , le console.log me montre Nouveau client connecté et Erreur: undefined

Serveur

//app.js

const express = require("express");
const router = express.Router();
router.get("/", (req, res) => {
  res.send({ response: "I am alive" }).status(200);
});
module.exports = router;

//index.js

const express = require("express");
const http = require("http");
const socketIo = require("socket.io");
const axios = require("axios");
const port = process.env.PORT || 4001;/How port in `chrome extension?`
const index = require("./routes/index");
const app = express();
app.use(index);
const server = http.createServer(app);
const io = socketIo(server); // < Interesting!
const token = "12345"; 


let interval;
io.on("connection", socket => {
  console.log("New client connected");
  if (interval) {
    clearInterval(interval);
  }
  interval = setInterval(() => getApiAndEmit(socket), 10000);
  socket.on("disconnect", () => {
    console.log("Client disconnected");
  });
});

const getApiAndEmit = async socket => {
    try {
      const res = await axios.get(
        "https://b.application.com/api/v1/scores?expand=createdBy"
      ); // Getting the data from DarkSky
      socket.emit("FromAPI", res.data); // Emitting a new message. It will be consumed by the client
    } catch (error) {
      console.error(`Error: ${error.code}`);
    }
  };

server.listen(port, () => console.log(`Listening on port ${port}`));

Client

//app.jsx

const token = '12345'

headers: {
  'Authorization': `Bearer $ {token}`
}


6 commentaires

S'il s'agit d'un script de contenu, Chrome n'autorise plus les requêtes d'origine croisée à cet endroit, voir la section 2 dans le explicatif officiel de CORB .


Dans l'application react, vous créez une connexion socket à https://b.application.com/api/v1/scores?expand=createdBy , vous ne devriez pas vous connecter à votre propre application serveur car votre application serveur semble envoyer une requête à cette URL et envoyer la réponse via le websocket.


@Titus Je dois donc changer mon point de terminaison dans le client app.jsx?


Pouvez-vous expliquer davantage le flux? Vous voulez que votre extension Chrome se connecte à votre serveur socket io et que votre serveur récupère les données du point de terminaison et les renvoie? Ou vous voulez que votre extension extrait directement les données du point de terminaison?


@MunimMunna Je récupère les données dans componentDidMount (), axios.get, url: https: //b.application.com/api/v1/scores? Développer = createdBy . Je souhaite récupérer des données sans recharger la page. Je ne veux pas actualiser la page à chaque fois.


@MunimMunna Je souhaite extraire des données de l'url: https://b.application.com/api/v1/scores?expand=createdBy . Connaissez-vous d'autres moyens que socket.io?


3 Réponses :


0
votes

Essayez de modifier app.jsx comme:
import socketIOClient from "socket.io-client";

class App extends Component {
    constructor(props) {
        super(props);
        this.state = {
            scores: [],
            receivedData:[],
            endpoint: "https://b.application.com/api/v1/scores?expand=createdBy",
            token: "12345"
        }
        this.onDataReceived = this.onDataReceived.bind(this);
        this.socket = socketIOClient(this.state.endpoint, {
            extraHeaders: {
                Authorization: `Bearer ${this.state.token}`
            }
        });
        this.socket.on("FromAPI", this.onDataReceived);
    }
    onDataReceived(receivedData) {
        console.log("receivedData ", receivedData);
        this.setState({
            receivedData: receivedData
        });
    }
        render() {
            return(
                <div></div>
            )
    }
}
export default App;

Essayez de modifier app.js: function getApiAndEmit

remplacez la ligne: socket.emit ("FromAPI" , res.data);

io.emit ("FromAPI", res.data);


3 commentaires

quelle est la valeur de receiveData? pouvez-vous s'il vous plaît élaborer?


c'est un tableau vide


Où puis-je mettre un jeton dans le serveur app.js?



4
votes
-----------Try Replacing app.js:- -----------------

const express = require("express");
const http = require("http");
const socketIo = require("socket.io");
const axios = require("axios");
const port = process.env.PORT || 4001;/How port in `chrome extension?`
const index = require("./routes/index");
const app = express();
app.use(index);
const server = http.createServer(app);
const io = socketIo(server); // < Interesting!
const token = "12345"; 
app.use(function(req, res, next) {
    res.header("Access-Control-Allow-Origin", "*");
    res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
    next();
});
let interval;
io.on("connection", socket => {
  console.log("New client connected");
  if (interval) {
    clearInterval(interval);
  }
  interval = setInterval(() => getApiAndEmit(socket), 10000);
  socket.on("disconnect", () => {
    console.log("Client disconnected");
  });
});

const getApiAndEmit = async socket => {
    try {
        const res = await axios("https://b.application.com/api/v1/scores?expand=createdBy", {
            method: 'GET',
            headers: {
                'Content-Type': 'application/json',
                "Access-Control-Allow-Origin": "*",
                'token': token
            }
        }); // Getting the data from DarkSky
        console.log("res.data:- "+JSON.stringify(res.data,null,4));
        socket.emit("FromAPI", res.data);  // Emitting a new message. It wil be consumed by the client
    } catch (error) {
        console.error(`Error: ${error.code}`);
    }
};

server.listen(port, () => console.log(`Listening on port ${port}`));

11 commentaires

Dans la console, je ne vois que Nouveau client connecté et Erreur: non défini


" b.application.com/api/v1/scores?expand=createdBy "vous essayez de récupérer des données à partir de la bonne api ?????


Oui. Je récupère les premières dates dans componentDidMount (), axios.get et c'était ok


remplacez la ligne d'erreur par console.error ("erreur: -", erreur); et laissez-moi savoir ce qu'il imprime


data: {error: "Votre demande a été effectuée avec des identifiants non valides." }}, isAxiosError: true . Le jeton est valide, car je l'utilise dans componentDidMount () et je récupère normalement des données


Savez-vous comment utiliser le facteur? Si oui, essayez d'abord d'obtenir la sortie à l'aide de postman, puis effectuez l'implémentation réelle.


Dans postman, j'ai choisi la méthode 'get' et 'headers', j'ai défini Content-Type, Access-Control-Allow-Origin et token. J'ai l'erreur "error": "Votre demande a été faite avec des informations d'identification non valides." }


Lorsque je choisis la méthode Postman «obtenir», l'autorisation «jeton porteur», je peux recevoir des dates. Le jeton est valide.


Je l'ai résolu. Les éléments que vous avez ajoutés ne sont pas nécessaires: app.use , Content-Type , Access-Control-Allow-Origin . Au lieu de token , vous devez ajouter Authorization: Bearer $ {token} . J'ai édité votre message et je l'ai corrigé. Votez pour vos intentions.


Merci et bravo ... Enfin, notre devise était la bonne solution.


continuons cette discussion dans le chat .



5
votes

Je l'ai résolu:

const getApiAndEmit = async socket => {
    try {
      const res = await axios.get(
        "https://b.application.com/api/v1/scores?expand=createdBy",
         headers: {
           Authorization: `Bearer ${token}`
         }
      ); 
      socket.emit("FromAPI", res.data); // Emitting a new message. It will be consumed by the client
    } catch (error) {
      console.error(`Error: ${error.code}`);
    }
  };


0 commentaires