1
votes

Comment obtenir les en-têtes de requête HTTP à partir de la requête de page initiale dans ReactJS

J'ai lu beaucoup de réponses mais je n'ai rien trouvé de satisfaisant. Les rôles des utilisateurs dans l'application dépendent des informations que je recevrai dans les en-têtes. J'ai déjà essayé ceci:

var req = new XMLHttpRequest(); req.open('GET', document.location,false); req.send(null); 
var headers = req.getAllResponseHeaders().toLowerCase(); alert(headers);

Mais je pense que je génère une nouvelle requête et d'ici là, l'URL change donc les en-têtes ne sont pas les mêmes. S'il y a une autre option pour obtenir les en-têtes, veuillez me guider avec la même

Modifier 1 (Cela clarifiera un peu plus la question):

  • L'utilisateur clique sur le lien de mon application (disons application1) via une autre application (disons application2).
  • Ensuite, l'applicaion2 enverra les en-têtes HTTP / HTTP dans les requêtes transmises par le proxy inverse, qui contiendront le rôle de l'utilisateur et quelques informations supplémentaires.
  • Dans les en-têtes, je recevrai les rôles des utilisateurs.
  • En fonction du rôle, le type d'accès serait déterminé et accordé à l'utilisateur


3 commentaires

les en-têtes de requête seront évidemment envoyés par le navigateur à votre serveur - ainsi, votre serveur peut lire ces en-têtes de requête ... et peut renvoyer les informations dans la réponse si vous le souhaitez (et vous pouvez écrire du code sur le serveur)


Votre question n'est pas très claire. Cependant, je vous suggère d'utiliser github.com/axios/axios pour les grandes applications.


@Sankalp Chawla, assurez-vous de marquer la réponse qui vous a aidé à résoudre le problème comme acceptée. Donc, cela aidera les futurs visiteurs.


3 Réponses :


0
votes

Comme cette question / réponse clarifie, obtenir les en-têtes de réponse d'origine pour la page n'est pas possible en javascript. Mais dans tous les cas, ce n'est pas le moyen d'obtenir un contrôle d'accès utilisateur robuste. Vous voulez plutôt que le serveur fournisse ces détails au client, après avoir lu et analysé les en-têtes de demande d'origine.


0 commentaires

0
votes

Si je comprends bien votre question, il semble que vous essayez d'obtenir les en-têtes de la requête lors du chargement initial de la page.

À l'heure actuelle, il n'y a pas d'API pour vous donner le HTTP en-têtes de réponse pour votre demande de page initiale. Cependant, vous pouvez obtenir et définir les en-têtes sur les requêtes AJAX.

1. Faire une requête ajax au chargement de la page.

La solution la plus simple est donc de simplement faire une requête AJAX au serveur lors du chargement de la page. Lorsque vous utilisez ReactJS , faites la demande sur componentDidMount a>

// Needed because the library uses browserify
var swgetheaders = require('swgetheaders');

// Register the service worker (with some options)
swgetheaders.registerServiceWorker('/swgetheaders-worker.js', {
    debug: true,
    corsExceptions: [
        'code.jquery.com',
        'platform.twitter.com'
    ]
});

swgetheaders.on('plugged', function() {
    console.log('The service worker is now activated and ready to listen to requests');
});

swgetheaders.on('response', function(request, response) {
    console.log('A response just arrived. We have both the request and the response:', request, response);
});

Voici le fonctionnement démo

2. Utiliser des web workers.

Une autre solution que je peux suggérer est de faire appel à des techniciens de service. Vous pouvez utiliser https://github.com/gmetais/sw-get-headers et implémentez-le dans votre application.

componentDidMount() {
    var req = new XMLHttpRequest();
    req.open('GET', document.location, false);
    req.send(null);
    var headers = req.getAllResponseHeaders().toLowerCase();
    headers = headers.split(/\n|\r|\r\n/g).reduce(function(a, b) {
        if (b.length) {
            var [ key, value ] = b.split(': ');
            a[key] = value;
        }
        return a;
    }, {});
    console.log(headers);
}


10 commentaires

J'ai parcouru la documentation des web workers mais je n'ai pas tout à fait compris ce qui se passe. Pouvez-vous expliquer un peu comment cela fonctionne?


De plus, j'ai trouvé ceci dans la documentation: Veuillez noter que le worker ne sera pas disponible au chargement de la première page, mais seulement après un changement de page ou un rechargement. Cela est dû à certaines limitations dans Service Workers. . Donc je suppose que cela va à l'encontre du but comme je l'ai expliqué dans ma question et j'ai déjà essayé la première option mais pas de chance.


Vous pouvez l'utiliser lors du chargement initial de la page. Il vous suffit d'enregistrer le worker dans votre composant React de niveau supérieur avant de procéder à l'autorisation, afin qu'il soit prêt avec les données pour autoriser les rôles. Je ne sais pas d'où vous avez obtenu les informations que vous avez mentionnées dans le commentaire ci-dessus. Les Webworkers seront disponibles dès que vous vous inscrivez dans votre application. Et il fonctionne sur un thread séparé, donc il utilise le mécanisme Broadcasting pour communiquer avec le thread principal.


Voici la documentation qui l'explique clairement developer.mozilla.org/ fr-FR / docs / Web / API / Web_Workers_API /…


Vous pouvez également vous référer au service worker que react crée lorsque vous créez une application à l'aide de create-react-app github.com/vish25v/react-todo-list/blob/master/src/... Et cette question a un exemple stackoverflow.com/questions/47475360/...


J'ai essayé cette approche: var swgetheaders = require ('./ swgetheaders-page'); // Enregistrer le service worker (avec quelques options) swgetheaders.registerServiceWorker ('./ swgetheaders-worker', {debug: true, corsExceptions: ['code.jquery.com', 'platform.twitter.com']}); Mais j'obtiens une erreur: TypeError: swgetheaders.registerServiceWorker n'est pas une fonction J'ai ajouté les deux fichiers dans le projet.


L'erreur est due à l'outil de construction que vous utilisez dans React. Le script est conçu pour fonctionner dans toutes les pages Web normales. Vous pouvez consulter ma démo codesandbox.io/s/so-page-header -service-worker-1tlgk Cette démo n'enregistre pas le worker en raison de la limitation du sandbox. Mais vous pouvez essayer la même chose localement.


J'ai essayé de faire la même chose localement et avec quelques ajustements également, mais cela ne fonctionne pas. Toujours coincé avec la même erreur.


Essayé de sandox ... toujours coincé avec le même problème


Il doit s'agir d'un problème d'importation ou d'un script. Cependant, je ne peux pas deviner quelle est la cause d'erreur dans votre cas. Vous pouvez peut-être créer un bac à sable pour reproduire le problème. Ou vous pouvez essayer avec la première approche dans ma réponse.



0
votes

Après avoir converti l'application en rendu côté serveur, j'ai pu obtenir les en-têtes avec le script suivant:

import path from 'path'
import fs from 'fs'
import express from 'express'
import React from 'react'
import ReactDOMServer from 'react-dom/server'
import { StaticRouter } from 'react-router-dom';
import App from '../src/App'
import UserContext from '../src/config/UserContext'
import serialize from "serialize-javascript"
const https = process.env.NODE_ENV === "production" ? require("spdy") : require("https")
var privateKey = fs.readFileSync(path.resolve(__dirname, "file.key"), 'utf8');
var certificate = fs.readFileSync(path.resolve(__dirname, "file.cer"), 'utf8');
var credentials = { key: privateKey, cert: certificate };

const tls = require('tls');
tls.DEFAULT_MIN_VERSION = 'TLSv1';

const PORT = anyport
const app = express()
var httpsServer = https.createServer(credentials, app);
const router = express.Router()



const serverRenderer = (req, res) => {
  const context = {};
  //console.log(req.headers);
  var a = 'anything';
  var b = 'anything';
  //console.log(req.headers["variable_name_in_header"]);
  var reqHeaders = req.headers;
  console.log(reqHeaders);
  if ("variable_name_in_header" in reqHeaders) {
   
    //anything

  }
  
  
  const initialState = { a, b };
  //const appString = ReactDOMServer.renderToString(<StaticRouter location={req.url} context={context}><App {...initialState} /></StaticRouter>);

  const appString = ReactDOMServer.renderToString(

    <StaticRouter location={req.url} context={context} basename={'/'}>
      <App {...initialState} />
    </StaticRouter>

  );

  fs.readFile(path.resolve('./build/index.html'), 'utf8', (err, data) => {
    if (err) {
      console.error(err)
      return res.status(500).send('An error occurred')
    }

    return res.send(
      data.replace(
        '</body>',
        `<script>window.__INITIAL_DATA__ = ${serialize(initialState)}</script></body>`
      ).replace(
        '<div id="root"></div>',
        `<div id="root">${appString}</div>`
      )
    )
  })

}

router.use('^/$', serverRenderer)

router.use(
  express.static(path.resolve(__dirname, '..', 'build'), { maxAge: '30d' })
)

// tell the app to use the above rules
app.use(router)

// app.use(express.static('./build'))
httpsServer.listen(PORT, () => {
  console.log(`SSR running on port ${PORT}`);
})


0 commentaires