You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

164 lines
5.0 KiB

4 years ago
  1. <h1 align="center">connect-history-api-fallback</h1>
  2. <p align="center">Middleware to proxy requests through a specified index page, useful for Single Page Applications that utilise the HTML5 History API.</p>
  3. [![Build Status](https://travis-ci.org/bripkens/connect-history-api-fallback.svg?branch=master)](https://travis-ci.org/bripkens/connect-history-api-fallback)
  4. [![Dependency Status](https://david-dm.org/bripkens/connect-history-api-fallback/master.svg)](https://david-dm.org/bripkens/connect-history-api-fallback/master)
  5. [![NPM](https://nodei.co/npm/connect-history-api-fallback.png?downloads=true&downloadRank=true)](https://nodei.co/npm/connect-history-api-fallback/)
  6. <h2>Table of Contents</h2>
  7. <!-- TOC depthFrom:2 depthTo:6 withLinks:1 updateOnSave:1 orderedList:0 -->
  8. - [Introduction](#introduction)
  9. - [Usage](#usage)
  10. - [Options](#options)
  11. - [index](#index)
  12. - [rewrites](#rewrites)
  13. - [verbose](#verbose)
  14. - [htmlAcceptHeaders](#htmlacceptheaders)
  15. - [disableDotRule](#disabledotrule)
  16. <!-- /TOC -->
  17. ## Introduction
  18. Single Page Applications (SPA) typically only utilise one index file that is
  19. accessible by web browsers: usually `index.html`. Navigation in the application
  20. is then commonly handled using JavaScript with the help of the
  21. [HTML5 History API](http://www.w3.org/html/wg/drafts/html/master/single-page.html#the-history-interface).
  22. This results in issues when the user hits the refresh button or is directly
  23. accessing a page other than the landing page, e.g. `/help` or `/help/online`
  24. as the web server bypasses the index file to locate the file at this location.
  25. As your application is a SPA, the web server will fail trying to retrieve the file and return a *404 - Not Found*
  26. message to the user.
  27. This tiny middleware addresses some of the issues. Specifically, it will change
  28. the requested location to the index you specify (default being `/index.html`)
  29. whenever there is a request which fulfills the following criteria:
  30. 1. The request is a GET request
  31. 2. which accepts `text/html`,
  32. 3. is not a direct file request, i.e. the requested path does not contain a
  33. `.` (DOT) character and
  34. 4. does not match a pattern provided in options.rewrites (see options below)
  35. ## Usage
  36. The middleware is available through NPM and can easily be added.
  37. ```
  38. npm install --save connect-history-api-fallback
  39. ```
  40. Import the library
  41. ```javascript
  42. var history = require('connect-history-api-fallback');
  43. ```
  44. Now you only need to add the middleware to your application like so
  45. ```javascript
  46. var connect = require('connect');
  47. var app = connect()
  48. .use(history())
  49. .listen(3000);
  50. ```
  51. Of course you can also use this piece of middleware with express:
  52. ```javascript
  53. var express = require('express');
  54. var app = express();
  55. app.use(history());
  56. ```
  57. ## Options
  58. You can optionally pass options to the library when obtaining the middleware
  59. ```javascript
  60. var middleware = history({});
  61. ```
  62. ### index
  63. Override the index (default `/index.html`)
  64. ```javascript
  65. history({
  66. index: '/default.html'
  67. });
  68. ```
  69. ### rewrites
  70. Override the index when the request url matches a regex pattern. You can either rewrite to a static string or use a function to transform the incoming request.
  71. The following will rewrite a request that matches the `/\/soccer/` pattern to `/soccer.html`.
  72. ```javascript
  73. history({
  74. rewrites: [
  75. { from: /\/soccer/, to: '/soccer.html'}
  76. ]
  77. });
  78. ```
  79. Alternatively functions can be used to have more control over the rewrite process. For instance, the following listing shows how requests to `/libs/jquery/jquery.1.12.0.min.js` and the like can be routed to `./bower_components/libs/jquery/jquery.1.12.0.min.js`. You can also make use of this if you have an API version in the URL path.
  80. ```javascript
  81. history({
  82. rewrites: [
  83. {
  84. from: /^\/libs\/.*$/,
  85. to: function(context) {
  86. return '/bower_components' + context.parsedUrl.pathname;
  87. }
  88. }
  89. ]
  90. });
  91. ```
  92. The function will always be called with a context object that has the following properties:
  93. - **parsedUrl**: Information about the URL as provided by the [URL module's](https://nodejs.org/api/url.html#url_url_parse_urlstr_parsequerystring_slashesdenotehost) `url.parse`.
  94. - **match**: An Array of matched results as provided by `String.match(...)`.
  95. - **request**: The HTTP request object.
  96. ### verbose
  97. This middleware does not log any information by default. If you wish to activate logging, then you can do so via the `verbose` option or by specifying a logger function.
  98. ```javascript
  99. history({
  100. verbose: true
  101. });
  102. ```
  103. Alternatively use your own logger
  104. ```javascript
  105. history({
  106. logger: console.log.bind(console)
  107. });
  108. ```
  109. ### htmlAcceptHeaders
  110. Override the default `Accepts:` headers that are queried when matching HTML content requests (Default: `['text/html', '*/*']`).
  111. ```javascript
  112. history({
  113. htmlAcceptHeaders: ['text/html', 'application/xhtml+xml']
  114. })
  115. ```
  116. ### disableDotRule
  117. Disables the dot rule mentioned above:
  118. > […] is not a direct file request, i.e. the requested path does not contain a `.` (DOT) character […]
  119. ```javascript
  120. history({
  121. disableDotRule: true
  122. })
  123. ```