使用grunt服务器,如何将所有请求redirect到根url?

我正在构build我的第一个Angular.js应用程序,并使用Yeoman 。

Yeoman使用Grunt允许您使用“grunt server”命令运行node.js连接服务器。

我在html5模式下运行我的angular度应用程序。 根据angular度文档,这需要修改服务器以将所有请求redirect到应用程序的根目录(index.html),因为angular度应用程序是单页面ajax应用程序。

“使用[html5]模式需要在服务器端重写URL,基本上你必须重写所有到你的应用程序入口点的链接(例如index.html)”

我试图解决的问题在这个问题中详细说明。

我如何修改我的grunt服务器以将所有页面请求redirect到index.html页面?

首先,使用你的命令行,用gruntfile导航到你的目录。

在CLI中input:

npm install --save-dev connect-modrewrite 

在你的咕噜文件的顶部把这个:

 var modRewrite = require('connect-modrewrite'); 

现在下一部分,你只想添加modRewrite到你的连接:

 modRewrite(['!\\.html|\\.js|\\.svg|\\.css|\\.png$ /index.html [L]']), 

这里是我的Gruntfile.js里的“connect”的例子。 你不需要担心我的lrSnippet和我的ssIncludes。 你需要的主要事情就是获取modRewrite。

  connect: { options: { port: 9000, // Change this to '0.0.0.0' to access the server from outside. hostname: '0.0.0.0', }, livereload: { options: { middleware: function (connect) { return [ modRewrite(['!\\.html|\\.js|\\.svg|\\.css|\\.png$ /index.html [L]']), lrSnippet, ssInclude(yeomanConfig.app), mountFolder(connect, '.tmp'), mountFolder(connect, yeomanConfig.app) ]; } } }, test: { options: { middleware: function (connect) { return [ mountFolder(connect, '.tmp'), mountFolder(connect, 'test') ]; } } }, dist: { options: { middleware: function (connect) { return [ mountFolder(connect, yeomanConfig.dist) ]; } } } }, 

FYI Yeoman / Grunt最近更改了新的Gruntfiles的默认模板。

复制默认的中间件逻辑为我工作:

 middleware: function (connect, options) { var middlewares = []; var directory = options.directory || options.base[options.base.length - 1]; // enable Angular's HTML5 mode middlewares.push(modRewrite(['!\\.html|\\.js|\\.svg|\\.css|\\.png$ /index.html [L]'])); if (!Array.isArray(options.base)) { options.base = [options.base]; } options.base.forEach(function(base) { // Serve static files. middlewares.push(connect.static(base)); }); // Make directory browse-able. middlewares.push(connect.directory(directory)); return middlewares; } 

更新:从grunt-contrib-connect 0.9.0开始,向连接服务器注入中间件要容易得多:

 module.exports = function (grunt) { // Load grunt tasks automatically require('load-grunt-tasks')(grunt); grunt.initConfig({ // The actual grunt server settings connect: { livereload: { options: { /* Support `$locationProvider.html5Mode(true);` * Requires grunt 0.9.0 or higher * Otherwise you will see this error: * Running "connect:livereload" (connect) task * Warning: Cannot call method 'push' of undefined Use --force to continue. */ middleware: function(connect, options, middlewares) { var modRewrite = require('connect-modrewrite'); // enable Angular's HTML5 mode middlewares.unshift(modRewrite(['!\\.html|\\.js|\\.svg|\\.css|\\.png$ /index.html [L]'])); return middlewares; } } } } }); } 

我为这个问题发送了一个pull请求: https : //github.com/yeoman/generator-angular/pull/132 ,但是你需要手动应用它。

为了深入简化@ Zuriel的回答,下面是我find的工作。

  • 安装connect-modrewrite: npm install connect-modrewrite --save
  • 将其包含在你的grunt文件中: var rewrite = require( "connect-modrewrite" );
  • 修改连接选项以使用重写:

     connect: { options: { middleware: function ( connect, options, middlewares ) { var rules = [ "!\\.html|\\.js|\\.css|\\.svg|\\.jp(e?)g|\\.png|\\.gif$ /index.html" ]; middlewares.unshift( rewrite( rules ) ); return middlewares; } }, server: { options: { port: 9000, base: "path/to/base" } } } 

尽可能简化这个。 因为您可以访问由连接提供的中间件,所以很容易将重写设置为第一优先级响应。 我知道这个问题已经被问了一段时间了,但这是谷歌search关于这个问题的最重要的结果之一。

想法来自源代码: https : //github.com/gruntjs/grunt-contrib-connect/blob/master/Gruntfile.js#L126-L139
规则string来自: http : //danburzo.ro/grunt/chapters/server/

我尝试了所有这些,但没有运气。 我正在编写一个angular2应用程序,解决scheme来自grunt-connect pushstate。 我所做的只是:

 npm install grunt-connect-pushstate --save 

并在咕噜文件中:

 var pushState = require('grunt-connect-pushstate/lib/utils').pushState; middleware: function (connect, options) { return [ // Rewrite requests to root so they may be handled by router pushState(), // Serve static files connect.static(options.base) ]; } 

这一切都像魔术一样运作。

https://www.npmjs.com/package/grunt-connect-pushstate