Add a Cache-Control: no-store header to the index.html response to instruct the browser to not cache the pages

Signed-off-by: Dominik Henneke <dominik.henneke@sda-se.com>
This commit is contained in:
Dominik Henneke
2021-03-05 13:41:52 +01:00
parent 98387ac6b5
commit 393b623aef
3 changed files with 49 additions and 8 deletions
+6
View File
@@ -0,0 +1,6 @@
---
'@backstage/plugin-app-backend': patch
---
Add a `Cache-Control: no-store` header to the `index.html` response to instruct the browser to not cache the pages.
This is a workaround for a missing `staticFallbackHandler` since an old `index.html` might link to static assets from a previous deployment.
+17 -1
View File
@@ -14,11 +14,11 @@
* limitations under the License.
*/
import { resolve as resolvePath } from 'path';
import { getVoidLogger } from '@backstage/backend-common';
import { ConfigReader } from '@backstage/config';
import express from 'express';
import Router from 'express-promise-router';
import { resolve as resolvePath } from 'path';
import request from 'supertest';
import { createRouter } from './router';
@@ -68,6 +68,22 @@ describe('createRouter', () => {
expect(response.status).toBe(200);
expect(response.text.trim()).toBe('this is index.html');
});
it.each(['/index.html', '/other.html', '/missing.html'])(
'returns %s with no-store Cache-Control header',
async file => {
const response = await request(app).get(file);
expect(response.header['cache-control']).toBe('no-store');
},
);
it.each(['/static/main.txt'])(
'returns %s with default Cache-Control header',
async file => {
const response = await request(app).get(file);
expect(response.header['cache-control']).toBe('public, max-age=0');
},
);
});
describe('createRouter with static fallback handler', () => {
+26 -7
View File
@@ -14,14 +14,14 @@
* limitations under the License.
*/
import { resolve as resolvePath } from 'path';
import express from 'express';
import Router from 'express-promise-router';
import { Logger } from 'winston';
import { notFoundHandler, resolvePackagePath } from '@backstage/backend-common';
import { Config } from '@backstage/config';
import { injectConfig, readConfigs } from '../lib/config';
import express from 'express';
import Router from 'express-promise-router';
import fs from 'fs-extra';
import { resolve as resolvePath } from 'path';
import { Logger } from 'winston';
import { injectConfig, readConfigs } from '../lib/config';
export interface RouterOptions {
config: Config;
@@ -95,9 +95,28 @@ export async function createRouter(
staticRouter.use(notFoundHandler());
router.use('/static', staticRouter);
router.use(express.static(appDistDir));
router.use(
express.static(appDistDir, {
setHeaders: (res, path) => {
// The Cache-Control header instructs the browser to not cache html files since it might
// link to static assets from recently deployed versions. This is a workaround when no
// staticFallbackHandler is configured.
// use `as any` since express uses mime v1 while we only have types for mime v2
if ((express.static.mime as any).lookup(path) === 'text/html') {
res.setHeader('Cache-Control', 'no-store');
}
},
}),
);
router.get('/*', (_req, res) => {
res.sendFile(resolvePath(appDistDir, 'index.html'));
res.sendFile(resolvePath(appDistDir, 'index.html'), {
headers: {
// The Cache-Control header instructs the browser to not cache the index.html since it might
// link to static assets from recently deployed versions. This is a workaround when no
// staticFallbackHandler is configured.
'cache-control': 'no-store',
},
});
});
return router;