node.js 使用 grunt 服务器,如何将所有请求重定向到 root url?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/17080494/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Using grunt server, how can I redirect all requests to root url?
提问by Charlie Martin
I am building my first Angular.jsapplication and I'm using Yeoman.
我正在构建我的第一个Angular.js应用程序,我正在使用Yeoman。
Yeoman uses Grunt to allow you to run a node.js connect server with the command 'grunt server'.
Yeoman 使用 Grunt 允许您使用命令“grunt server”运行 node.js 连接服务器。
I'm running my angular application in html5 mode. According to the angular docs, this requires a modification of the server to redirect all requests to the root of the application (index.html), since angular apps are single page ajax applications.
我正在 html5 模式下运行我的 angular 应用程序。根据 angular 文档,这需要修改服务器以将所有请求重定向到应用程序的根目录 (index.html),因为 angular 应用程序是单页 ajax 应用程序。
"Using [html5] mode requires URL rewriting on server side, basically you have to rewrite all your links to entry point of your application (e.g. index.html)"
“使用 [html5] 模式需要在服务器端重写 URL,基本上你必须重写所有指向应用程序入口点的链接(例如 index.html)”
The problem that I'm trying to solve is detailed in thisquestion.
我试图解决的问题在这个问题中有详细说明。
How can I modify my grunt server to redirect all page requests to the index.html page?
如何修改我的 grunt 服务器以将所有页面请求重定向到 index.html 页面?
回答by Zuriel
First, using your command line, navigate to your directory with your gruntfile.
首先,使用命令行,使用 gruntfile 导航到您的目录。
Type this in the CLI:
在 CLI 中输入:
npm install --save-dev connect-modrewrite
At the top of your grunt file put this:
在你的 grunt 文件的顶部放这个:
var modRewrite = require('connect-modrewrite');
Now the next part, you only want to add modRewriteinto your connect:
现在是下一部分,您只想将modRewrite添加到您的连接中:
modRewrite(['!\.html|\.js|\.svg|\.css|\.png$ /index.html [L]']),
Here is a example of what my "connect" looks like inside my Gruntfile.js. You don't need to worry about my lrSnippet and my ssIncludes. The main thing you need is to just get the modRewrite in.
这是我的“连接”在 Gruntfile.js 中的样子的示例。您无需担心我的 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)
];
}
}
}
},
回答by Steve Jansen
FYI Yeoman/Grunt recently changed the default template for new Gruntfiles.
仅供参考 Yeoman/Grunt 最近更改了新 Gruntfiles 的默认模板。
Copying the default middlewares logicworked for me:
复制默认的中间件逻辑对我有用:
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;
}
UPDATE:As of grunt-contrib-connect 0.9.0, injecting middlewares into the connect server is much easier:
更新:从 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;
}
}
}
}
});
}
回答by L42y
There is a pull request I sent for this problem: https://github.com/yeoman/generator-angular/pull/132, but you need to apply it manually.
我为此问题发送了一个拉取请求:https: //github.com/yeoman/generator-angular/pull/132,但您需要手动应用它。
回答by dmaloney.calu
To deeply simplify @Zuriel's answer, here's what I found to work on my behalf.
为了深入简化@Zuriel 的回答,以下是我发现可以代表我工作的内容。
- Install connect-modrewrite:
npm install connect-modrewrite --save - Include it in your grunt file:
var rewrite = require( "connect-modrewrite" ); Modify your connect options to use the rewrite:
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" } } }
- 安装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" } } }
Simplified this as much as possible. Because you have access to the middlewares provided by connect, it's easy to set the rewrite to the first priority response. I know it's been a while since the question has been asked, but this is one of the top results of google searching regarding the problem.
尽可能简化这一点。因为您可以访问 connect 提供的中间件,所以很容易将重写设置为第一优先级响应。我知道自从提出这个问题以来已经有一段时间了,但这是谷歌搜索有关该问题的最佳结果之一。
Idea came from source code: https://github.com/gruntjs/grunt-contrib-connect/blob/master/Gruntfile.js#L126-L139
Rules string from: http://danburzo.ro/grunt/chapters/server/
想法来自源代码:https: //github.com/gruntjs/grunt-contrib-connect/blob/master/Gruntfile.js#L126-L139
规则字符串来自:http: //danburzo.ro/grunt/chapters/server /
回答by Tomer Almog
I tried all of these, but had no luck. I am writing an angular2 app, and the solution came from grunt-connect pushstate. All I did was:
我尝试了所有这些,但没有运气。我正在编写一个 angular2 应用程序,解决方案来自 grunt-connect pushstate。我所做的只是:
npm install grunt-connect-pushstate --save
and in the grunt file:
并在 grunt 文件中:
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)
];
}
and it all worked like magic.
这一切都像魔术一样运作。

