client/js/router.js: Reads <base> href tag
This commit is contained in:
parent
defada45ab
commit
565027269c
5 changed files with 68 additions and 19 deletions
40
INSTALL.md
40
INSTALL.md
|
@ -63,3 +63,43 @@ and Docker Compose (version 1.6.0 or greater) already installed.
|
||||||
# To stop
|
# To stop
|
||||||
user@host:szuru$ docker-compose down
|
user@host:szuru$ docker-compose down
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### Additional Features
|
||||||
|
|
||||||
|
1. **Using a seperate domain to host static files (image content)**
|
||||||
|
|
||||||
|
If you want to host your website on, (`http://example.com/`) but want
|
||||||
|
to serve the images on a different domain, (`http://static.example.com/`)
|
||||||
|
then you can run the backend container with an additional environment
|
||||||
|
variable `DATA_URL=http://static.example.com/`. Make sure that this
|
||||||
|
additional host has access contents to the `/data` volume mounted in the
|
||||||
|
backend.
|
||||||
|
|
||||||
|
2. **Setting a specific base URI for proxying**
|
||||||
|
|
||||||
|
Some users may wish to access the service at a different base URI, such
|
||||||
|
as `http://example.com/szuru/`, commonly when sharing multiple HTTP
|
||||||
|
services on one domain using a reverse proxy. In this case, simply set
|
||||||
|
`BASE_URL="/szuru/"` in the frontend container, and
|
||||||
|
`DATA_URL="/szuru/data/"` in the backend container (unless you are hosting
|
||||||
|
your data on a different domain).
|
||||||
|
|
||||||
|
You should set your reverse proxy to proxy `http(s)://example.com/szuru` to
|
||||||
|
`http://<internal IP or hostname of frontend container>/`. For an NGINX
|
||||||
|
reverse proxy, that will appear as:
|
||||||
|
|
||||||
|
```nginx
|
||||||
|
location /szuru {
|
||||||
|
proxy_http_version 1.1;
|
||||||
|
proxy_pass http://<internal IP or hostname of frontend container>/;
|
||||||
|
|
||||||
|
proxy_set_header Host $http_host;
|
||||||
|
proxy_set_header Upgrade $http_upgrade;
|
||||||
|
proxy_set_header Connection "upgrade";
|
||||||
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||||
|
proxy_set_header X-Scheme $scheme;
|
||||||
|
proxy_set_header X-Real-IP $remote_addr;
|
||||||
|
proxy_set_header X-Forwarded-Proto $scheme;
|
||||||
|
proxy_set_header X-Script-Name /szuru;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
|
@ -8,9 +8,10 @@ COPY . ./
|
||||||
|
|
||||||
ARG BUILD_INFO="docker-latest"
|
ARG BUILD_INFO="docker-latest"
|
||||||
ARG CLIENT_BUILD_ARGS=""
|
ARG CLIENT_BUILD_ARGS=""
|
||||||
RUN node build.js ${CLIENT_BUILD_ARGS}
|
RUN BASE_URL="__BASEURL__" node build.js ${CLIENT_BUILD_ARGS}
|
||||||
|
|
||||||
RUN find public/ -type f -size +5k -print0 | xargs -0 -- gzip -6 -k
|
RUN find public/ -name public/index.html -prune -o -type f -size +5k \
|
||||||
|
-print0 | xargs -0 -- gzip -6 -k
|
||||||
|
|
||||||
|
|
||||||
FROM nginx:alpine
|
FROM nginx:alpine
|
||||||
|
@ -21,6 +22,7 @@ RUN \
|
||||||
echo "#!/bin/sh" >> /init && \
|
echo "#!/bin/sh" >> /init && \
|
||||||
echo 'sed -i "s|__BACKEND__|${BACKEND_HOST}|" /etc/nginx/nginx.conf' \
|
echo 'sed -i "s|__BACKEND__|${BACKEND_HOST}|" /etc/nginx/nginx.conf' \
|
||||||
>> /init && \
|
>> /init && \
|
||||||
|
echo 'sed -i "s|__BASEURL__|${BASE_URL:-/}|" /var/www/index.htm' >> /init && \
|
||||||
echo 'exec nginx -g "daemon off;"' >> /init && \
|
echo 'exec nginx -g "daemon off;"' >> /init && \
|
||||||
chmod a+x /init
|
chmod a+x /init
|
||||||
|
|
||||||
|
|
|
@ -65,7 +65,10 @@ function bundleHtml() {
|
||||||
const underscore = require('underscore');
|
const underscore = require('underscore');
|
||||||
const babelify = require('babelify');
|
const babelify = require('babelify');
|
||||||
const baseHtml = readTextFile('./html/index.htm', 'utf-8');
|
const baseHtml = readTextFile('./html/index.htm', 'utf-8');
|
||||||
writeFile('./public/index.htm', minifyHtml(baseHtml));
|
const baseUrl = process.env.BASE_URL ? process.env.BASE_URL : '/';
|
||||||
|
const finalHtml = baseHtml.replace(
|
||||||
|
'<!-- Base HTML Placeholder -->', `<base href="${baseUrl}"/>`);
|
||||||
|
writeFile('./public/index.htm', minifyHtml(finalHtml));
|
||||||
|
|
||||||
glob('./html/**/*.tpl', {}, (er, files) => {
|
glob('./html/**/*.tpl', {}, (er, files) => {
|
||||||
let compiledTemplateJs = '\'use strict\'\n';
|
let compiledTemplateJs = '\'use strict\'\n';
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
<meta name='msapplication-TileColor' content='#ffffff'/>
|
<meta name='msapplication-TileColor' content='#ffffff'/>
|
||||||
<meta name="msapplication-TileImage" content="/img/mstile-150x150.png">
|
<meta name="msapplication-TileImage" content="/img/mstile-150x150.png">
|
||||||
<title>Loading...</title>
|
<title>Loading...</title>
|
||||||
<base href="/"/>
|
<!-- Base HTML Placeholder -->
|
||||||
<link href='css/app.min.css' rel='stylesheet' type='text/css'/>
|
<link href='css/app.min.css' rel='stylesheet' type='text/css'/>
|
||||||
<link href='css/vendor.min.css' rel='stylesheet' type='text/css'/>
|
<link href='css/vendor.min.css' rel='stylesheet' type='text/css'/>
|
||||||
<link rel='shortcut icon' type='image/png' href='img/favicon.png'/>
|
<link rel='shortcut icon' type='image/png' href='img/favicon.png'/>
|
||||||
|
|
|
@ -14,24 +14,29 @@ const clickEvent = document.ontouchstart ? 'touchstart' : 'click';
|
||||||
const uri = require('./util/uri.js');
|
const uri = require('./util/uri.js');
|
||||||
let location = window.history.location || window.location;
|
let location = window.history.location || window.location;
|
||||||
|
|
||||||
const base = '';
|
function _getOrigin() {
|
||||||
|
return location.protocol + '//' + location.hostname
|
||||||
|
+ (location.port ? (':' + location.port) : '');
|
||||||
|
}
|
||||||
|
|
||||||
function _isSameOrigin(href) {
|
function _isSameOrigin(href) {
|
||||||
let origin = location.protocol + '//' + location.hostname;
|
return href && href.indexOf(_getOrigin()) === 0;
|
||||||
if (location.port) {
|
}
|
||||||
origin += ':' + location.port;
|
|
||||||
}
|
function _getBaseHref() {
|
||||||
return href && href.indexOf(origin) === 0;
|
const bases = document.getElementsByTagName('base');
|
||||||
|
return bases.length > 0 ?
|
||||||
|
bases[0].href.replace(_getOrigin(), '').replace(/\/+$/, '') : '';
|
||||||
}
|
}
|
||||||
|
|
||||||
class Context {
|
class Context {
|
||||||
constructor(path, state) {
|
constructor(path, state) {
|
||||||
if (path[0] === '/' && path.indexOf(base) !== 0) {
|
const base = _getBaseHref();
|
||||||
path = base + path;
|
path = path.indexOf('/') !== 0 ? '/' + path : path;
|
||||||
}
|
path = path.indexOf(base) !== 0 ? base + path : path;
|
||||||
|
|
||||||
this.canonicalPath = path;
|
this.canonicalPath = path;
|
||||||
this.path = path.replace(base, '') || '/';
|
this.path = !path.indexOf(base) ? path.slice(base.length) : path;
|
||||||
|
|
||||||
this.title = document.title;
|
this.title = document.title;
|
||||||
this.state = state || {};
|
this.state = state || {};
|
||||||
|
@ -289,15 +294,14 @@ const _onClick = router => {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let path = el.pathname + el.search + (el.hash || '');
|
const base = _getBaseHref();
|
||||||
|
const orig = el.pathname + el.search + (el.hash || '');
|
||||||
|
const path = !orig.indexOf(base) ? orig.slice(base.length) : orig;
|
||||||
|
|
||||||
const orig = path;
|
|
||||||
if (path.indexOf(base) === 0) {
|
|
||||||
path = path.substr(base.length);
|
|
||||||
}
|
|
||||||
if (base && orig === path) {
|
if (base && orig === path) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
router.show(orig);
|
router.show(orig);
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in a new issue