简体   繁体   English

使用带有nodeJS和Express的AngularJS html5mode

[英]using AngularJS html5mode with nodeJS and Express

I'm using a nodeJS server with Express to serve my AngularJS application. 我正在使用带有Express的nodeJS服务器来为我的AngularJS应用程序提供服务。 This all works fine when I'm using angularJS default routes (hashbangs), but now I'm trying to activate html5 mode. 当我使用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: 这就是我的nodeJS app.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.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? 我怎么做才能让angularJS html5mode与nodeJS和Express一起工作? Thanks. 谢谢。

Your initial fix (declaring static middleware handlers for specific prefixes) should work just fine, but you need to make sure they are declared before any 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-all处理程序来测试,看看是否有任何JS / CSS / ...请求正常工作)。

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
    });
});

I'm working on a web application using Angularjs and Requirejs on the client, with Nodejs on the server. 我正在使用客户端上的Angularjs和Requirejs处理Web应用程序,并在服务器上使用Nodejs。

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 Apploader文件

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'
    }

 }

})

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM