javascript 在 nodeJS 和 Express 中使用 AngularJS html5mode
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/17777967/
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 AngularJS html5mode with nodeJS and Express
提问by Jakemmarsh
I'm using a nodeJS server with Express to serve my AngularJS application. This all works fine when I'm using angularJS default routes (hashbangs), but now I'm trying to activate html5 mode.
我正在使用带有 Express 的 nodeJS 服务器来为我的 AngularJS 应用程序提供服务。当我使用 angularJS 默认路由(hashbangs)时,这一切都很好,但现在我正在尝试激活 html5 模式。
I'm activating html5mode like this:
我正在像这样激活 html5mode:
$locationProvider.html5Mode(true).hashPrefix('!');
And this is what my nodeJS app.js
file looks like:
这就是我的 nodeJSapp.js
文件的样子:
var path = require('path'),
express = require('express'),
app = express(),
routes = require(path.join(__dirname, 'routes'));
app.configure(function() {
app.use(express.logger('dev'));
app.use(express.compress());
app.use(express.methodOverride());
app.use(express.bodyParser());
app.use(app.router);
app.all("/*", function(req, res, next) {
res.sendfile("index.html", { root: __dirname + "/../app" });
});
app.use(express.errorHandler({
dumpExceptions: true,
showStack: true
}));
});
However, this now serves all requests as my index.html
file, and so I get the following error from requireJS:
但是,这现在将所有请求作为我的index.html
文件提供,因此我从 requireJS 收到以下错误:
Uncaught SyntaxError: Unexpected token <
I tried adding the following to my nodeJS app.js
so it would serve my resources correctly:
我尝试将以下内容添加到我的 nodeJS 中,app.js
以便它可以正确地为我的资源提供服务:
app.use("/js", express.static(__dirname + "/../app/js"));
app.use("/img", express.static(__dirname + "/../app/img"));
app.use("/css", express.static(__dirname + "/../app/css"));
app.use("/partials", express.static(__dirname + "/../app/partials"));
but still no luck.
但仍然没有运气。
I also tried replacing the app.all
statement with:
我还尝试将app.all
语句替换为:
app.use(function(req, res) {
// Use res.sendfile, as it streams instead of reading the file into memory.
res.sendfile(__dirname + '/../app/index.html');
});
but that didn't work either. What can I do to get angularJS html5mode working with nodeJS and Express? Thanks.
但这也不起作用。我该怎么做才能让 angularJS html5mode 与 nodeJS 和 Express 一起工作?谢谢。
采纳答案by robertklep
Your initial fix (declaring static middleware handlers for specific prefixes) should work just fine, but you need to make sure they are declared beforeany other routes (and app.router
, although you don't need to explicitly use it):
您的初始修复(为特定前缀声明静态中间件处理程序)应该可以正常工作,但您需要确保在任何其他路由之前声明它们(并且app.router
,尽管您不需要显式使用它):
// these need to go first:
app.use("/js", express.static(__dirname + "/../app/js"));
app.use("/img", express.static(__dirname + "/../app/img"));
app.use("/css", express.static(__dirname + "/../app/css"));
app.use("/partials", express.static(__dirname + "/../app/partials"));
// any other routes:
app.all("/*", ...);
Also, you need to make sure that the prefixed static handlers are actually declared okay (correct path), otherwise they won't be able to find any requested files and the requests will pass down the middleware chain and ultimately be handled by the catch-all handler (should be easy enough to test by commenting out the catch-all handler and see if any JS/CSS/... requests work okay).
此外,您需要确保前缀静态处理程序实际上已声明为正常(正确路径),否则它们将无法找到任何请求的文件,并且请求将向下传递到中间件链并最终由 catch- 处理-所有处理程序(应该很容易通过注释掉所有处理程序来测试,看看是否有任何 JS/CSS/... 请求工作正常)。
回答by Connor Leech
Configure express 4 server like:
配置 express 4 服务器,如:
app.use(express.static(__dirname + '/public'));
app.get('/*', function(req, res){
res.sendFile(__dirname + '/public/index.html');
});
and angular like:
和角度像:
app.config(function($stateProvider, $urlRouterProvider, $locationProvider){
$stateProvider
.state('home', {
url: '/',
templateUrl: 'templates/main.html'
})
.state('register', {
url: '/register',
templateUrl: 'templates/register.html'
});
$urlRouterProvider.otherwise("/");
$locationProvider.html5Mode({
enabled: true,
requireBase: false
});
});
回答by Zakaria Ali Osman
I'm working on a web application using Angularjs and Requirejs on the client, with Nodejs on the server.
我正在开发一个在客户端使用 Angularjs 和 Requirejs,在服务器上使用 Nodejs 的 Web 应用程序。
Here is some sample code to show you how I set it up.
这是一些示例代码,向您展示我如何设置它。
Note this example is showing a hash url but you can easily change that by modifying the middleware function and angular configuration
请注意,此示例显示了一个哈希 url,但您可以通过修改中间件功能和角度配置轻松更改它
Middleware function
中间件功能
isXHR: function (req, res, next) {
if (req.xhr || req.get("angular-request") === "ajaxRequest") {
next();
} else {
var url = req.url;
var urls = url.split("/");
var last = _.last(urls);
urls = _.without(urls, last);
url = urls.join("/") + "#/" + last //remove the hash if you want to make it html5mode;
res.redirect(url);
}
}
Server route configuration
服务器路由配置
//I'm using express-namespace to group my routes
app.namespace("/requirements", function(){
//Shared local variable used across the application
var info = {
app: {
title: "Requirements",
module: "app/requirements" // where the angular application stored
}
}
//this is the main url that will user request
Route.get("/", function (req, res) {
res.cookie("profileRegisterationSteps", 0);
res.render("app/requirements/index", info);
});
//this is the url angular js will request
Route.get("type", filters.isXHR, function (req, res) {
res.render("app/requirements/profile/type", info);
});
})
Client route configuration
客户端路由配置
require(['App', 'underscore', 'ngAmd'/*angular amd*/, 'autoload'/*No Sense*/, 'appLoader' /*i used to load my scripts file for the route user requested (not all scripts files only who requested) before template laoded*/, 'appRoute'/*this is a list of routes*/], function (app, _, amd, autoload, loader, routes) {
app.config(function ($routeProvider, $locationProvider, $httpProvider) {
//remove a clearn URL
$locationProvider.html5Mode(false);
//ku dar header kan si uu server ka u ogaado Request in yahay Ajax
$httpProvider.defaults.headers.common['angular-request'] = "ajaxRequest";
//Route Config
var Route = $routeProvider;
//get all routes objects that defined in routes module
_.each(routes, function (route) {
// extend the routes module objects and use its properties
Route.when(route.url, _.extend(route, {
//call returning function in loader module and write the promise
resolve: _.extend(loader(route))
}));
});
Route.otherwise({
redirectTo: "/"
});
});
//start the application
amd.bootstrap(app);
});
Apploader file
应用程序文件
require.config({
paths: {
//pages
type: "Apps/requirements/pages/type"
}
});
define(['App'], function(app) {
return function (options) {
return {
loader: function ($q, $rootScope) {
var defer = $q.defer();
var module = options.name// the name of the route (this name corresponds to the requirejs module name above;
if (!!(module)) {
if (require.defined(module)) {
defer.resolve();
} else {
require([module], function () {
$rootScope.safeApply(function () {
defer.resolve();
})
});
}
} else {
defer.resolve();
}
return defer.promise;
}
}
}
});
Routes file
路由文件
define(function(){
return {
{
name : "type",
url : "/",
templateUrl : "/requirements/type",
view : 'services'
}
}
})