Setup front-end to work with a basepath

React-router and also the client that we use in the frontend need to be
informed on how to access the Chronograf backend when it's being hosted
on a route other than /. To accomplish this, a data attribute is written
into the `<div>` which serves as our React root. We then make the React
router aware of this if it's set and also pass the prefix to axios (our
front end HTTP client) by way of window.

Originally, it was desired to have the basepath accessible via an API,
but this proved to be impossible because to access that API, the front
end would already need to know the basepath. The technique we went with
was arrived at independently, but is also used by Jupityr notebooks
which encountered the same problem.
pull/814/head
Tim Raymond 2017-01-26 17:04:03 -05:00
parent cf243794af
commit 609b7a1d1a
4 changed files with 20 additions and 2 deletions

View File

@ -60,6 +60,7 @@ func Assets(opts AssetsOpts) http.Handler {
[]byte(`src="`),
[]byte(`href="`),
[]byte(`url(`),
[]byte(`data-basepath="`), // for forwarding basepath to frontend
},
}
up.ServeHTTP(w, r)

View File

@ -1,7 +1,8 @@
import React from 'react';
import {render} from 'react-dom';
import {Provider} from 'react-redux';
import {Router, Route, browserHistory, Redirect} from 'react-router';
import {Router, Route, Redirect} from 'react-router';
import {createHistory, useBasename} from 'history';
import App from 'src/App';
import AlertsApp from 'src/alerts';
@ -28,6 +29,19 @@ const timeRange = Object.assign(defaultTimeRange, parsedTimeRange);
const store = configureStore({timeRange});
const rootNode = document.getElementById('react-root');
let browserHistory;
const basepath = rootNode.dataset.basepath;
window.basepath = basepath;
if (basepath) {
browserHistory = useBasename(createHistory)({
basename: basepath, // this is written in when available by the URL prefixer middleware
});
} else {
browserHistory = useBasename(createHistory)({
basename: "",
});
}
const Root = React.createClass({
getInitialState() {
return {

View File

@ -5,6 +5,6 @@
<title>Chronograf</title>
</head>
<body>
<div id='react-root'></div>
<div id='react-root' data-basepath=""></div>
</body>
</html>

View File

@ -7,6 +7,9 @@ export default function AJAX({
params = {},
headers = {},
}) {
if (window.basepath) {
url = `${window.basepath}${url}`;
}
return axios({
url,
method,