【问题标题】:How to get the HTTP request headers from initial page request in ReactJS如何从 ReactJS 中的初始页面请求中获取 HTTP 请求标头
【发布时间】:2020-02-13 22:52:21
【问题描述】:

我已经阅读了很多答案,但找不到任何令人满意的答案。应用程序中的用户角色取决于我将在标题中收到的信息。 我已经试过了:

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

但我想我会生成一个新请求,然后 URL 会发生变化,因此标题不一样。 如果有任何其他选项来获取标题,请用同样的方法指导我

编辑 1(这将进一步澄清问题):

  • 用户会通过另一个应用程序(假设是 application2)点击我的应用程序(假设是 application1)链接。
  • 然后,applicaion2 将在反向代理转发的请求中发送 HTTP/HTTPS 标头,其中将包含用户角色和更多信息。
  • 我将在标题中接收用户角色。
  • 根据角色确定访问类型并将其授予用户

【问题讨论】:

  • 请求标头显然会由浏览器发送到您的服务器 - 因此,您的服务器可以读取这些请求标头......并且可以根据需要在响应中发回信息(并且您可以在服务器上写代码)
  • 你的问题不是很清楚。但是,对于大型应用程序,我建议您使用github.com/axios/axios
  • @Sankalp Chawla,确保将帮助您解决问题的答案标记为已接受。因此,它将帮助未来的访问者。

标签: javascript reactjs http http-headers


【解决方案1】:

正如question/answer 澄清的那样,在 javascript 中无法获取页面的原始响应标头。但无论如何,这都不是实现稳健的用户访问控制的方法。相反,您希望服务器在读取并解析原始请求标头后将这些详细信息提供给客户端。

【讨论】:

    【解决方案2】:

    如果我正确理解您的问题,您似乎正在尝试在初始页面加载时获取请求 headers

    目前,没有 API 可以为您的初始页面请求提供 HTTP response headers。但是,您可以在 AJAX 请求上使用 getset 标头。

    1。在页面加载时发出 ajax 请求。

    因此,更简单的解决方案是在页面加载时简单地向服务器发出 AJAX 请求。当您使用ReactJS 时,请在componentDidMount 上提出请求

    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);
    }
    

    这是工作的demo

    2。使用网络工作者。

    我可以建议的另一个解决方案是寻求服务人员的帮助。 您可以使用https://github.com/gmetais/sw-get-headers 并在您的应用程序中实现它。

    // 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);
    });
    

    【讨论】:

    • 我浏览了网络工作者的文档,但我不太明白发生了什么。你能解释一下它是如何工作的吗?
    • 此外,我在文档中发现了这一点:请注意,工作人员在第一次加载页面时将不可用,但只有在页面更改或重新加载后才可用。这是由于 Service Worker 的一些限制。。所以我想它违背了我在问题中解释的目的,我已经尝试了第一个选项,但没有运气。
    • 您可以在初始页面加载时使用它。在进行授权之前,您只需在顶级 React componet 中注册工作人员,以便准备好数据来授权角色。我不确定您从哪里获得上述评论中提到的信息。一旦您在应用程序中注册,Webworkers 将立即可用。而且它运行在一个单独的线程上,所以它使用Broadcasting机制与主线程通信。
    • 你也可以参考使用create-react-appgithub.com/vish25v/react-todo-list/blob/master/src/…创建应用程序时反应创建的服务工作者这个问题有一些例子stackoverflow.com/questions/47475360/…
    【解决方案3】:

    将应用程序转换为服务器端渲染后,我能够使用以下脚本获取标题:

    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}`);
    })

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-02-25
      • 2020-04-07
      • 1970-01-01
      • 2023-03-28
      • 2012-10-20
      • 1970-01-01
      相关资源
      最近更新 更多