I have read a lot of answers but couldn't able to find anything satisfactory. The user roles in the application depend on the information I will receive in headers. I have already tried this:
var req = new XMLHttpRequest(); req.open('GET', document.location,false); req.send(null);
var headers = req.getAllResponseHeaders().toLowerCase(); alert(headers);
But i think i generates a new request and by then the URL changes so the headers are not the same. If there is any other option to get the headers please guide me with the same
Edit 1 (This will clarify the question a little more):
- The user would click on my application(Let's say application1) link via another application (Let's say application2).
- Then the applicaion2 will send the HTTP/HTTPs headers in requests forwarded by the reverse proxy, which will contain user role and some more information.
- In the headers I will receive user roles.
- Depending on the role the kind of access would be determined and given to user
I have read a lot of answers but couldn't able to find anything satisfactory. The user roles in the application depend on the information I will receive in headers. I have already tried this:
var req = new XMLHttpRequest(); req.open('GET', document.location,false); req.send(null);
var headers = req.getAllResponseHeaders().toLowerCase(); alert(headers);
But i think i generates a new request and by then the URL changes so the headers are not the same. If there is any other option to get the headers please guide me with the same
Edit 1 (This will clarify the question a little more):
- The user would click on my application(Let's say application1) link via another application (Let's say application2).
- Then the applicaion2 will send the HTTP/HTTPs headers in requests forwarded by the reverse proxy, which will contain user role and some more information.
- In the headers I will receive user roles.
- Depending on the role the kind of access would be determined and given to user
- 1 the request headers will obviously be sent by the browser to your server - so, your server can read these request headers ... and can send the info back in the response if you want (and you can write code on the server) – Bravo Commented Oct 17, 2019 at 5:39
- Your question is not very clear. However, I suggest you to use github./axios/axios for large applications. – James Commented Oct 17, 2019 at 5:40
- @Sankalp Chawla, Make sure you mark the answer which helped you to solve the issue as accepted. So, it will help the future visitors. – James Commented Oct 17, 2019 at 6:38
3 Answers
Reset to default 0As this question/answer clarifies, getting the original response headers for the page is not possible in javascript. But in any case, this is not the way to achieve robust user access control. Rather, you want the server to provide those details to the client, having read and parsed the original request headers.
If I understand your question correctly, It seems you are trying to get the request headers
on initial page load.
At present, there is no API to give you the HTTP response headers
for your initial page request. However, you can get
and set
headers on AJAX requests.
1. Make an ajax request on page load.
So, the easier solution is to simply make an AJAX request to the server on page load. As you are using ReactJS
, make the request on ponentDidMount
ponentDidMount() {
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);
}
Here is the working demo
2. Using web workers.
Another solution I can suggest is to take help of service workers. You can use https://github./gmetais/sw-get-headers and implement it in your application.
// 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.',
'platform.twitter.'
]
});
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);
});
After converting the application to server-side rendering I was able to get the headers with the following script:
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}`);
})