如何从ReactJS的初始页面请求中获取HTTP请求标头

时间:2019-10-17 05:28:18

标签: javascript reactjs

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

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

但是我认为我生成了一个新请求,然后URL发生了变化,因此标头不一样。 如果还有其他获取标题的选项,请用相同的指导

编辑1(这将使问题更清楚):

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

3 个答案:

答案 0 :(得分:0)

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

答案 1 :(得分:0)

如果我正确理解了您的问题,则似乎是您在尝试在初始页面加载时获得请求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);
});

答案 2 :(得分:0)

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

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

相关问题