簡體   English   中英

如何從 ReactJS 中的初始頁面請求中獲取 HTTP 請求標頭

[英]How to get the HTTP request headers from initial page request in 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)鏈接。
  • 然后,applicaion2 將在反向代理轉發的請求中發送 HTTP/HTTPS 標頭,其中將包含用戶角色和更多信息。
  • 在標題中,我將收到用戶角色。
  • 根據角色,將確定訪問類型並將其提供給用戶

正如這個問題/答案所闡明的,在 javascript 中無法獲取頁面的原始響應標頭。 但無論如何,這都不是實現穩健的用戶訪問控制的方法。 相反,您希望服務器在讀取並解析原始請求標頭后將這些詳細信息提供給客戶端。

如果我正確理解您的問題,您似乎正在嘗試在初始頁面加載時獲取請求headers

目前,沒有 API 可以為您的初始頁面請求提供HTTP response headers 但是,您可以getset AJAX 請求的標頭。

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

這是工作演示

2. 使用 web 工人。

我可以建議的另一個解決方案是尋求服務人員的幫助。 您可以使用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);
});

將應用程序轉換為服務器端渲染后,我能夠使用以下腳本獲取標頭:

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM