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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-27 09:35:52  来源:igfitidea点击:

using AngularJS html5mode with nodeJS and Express

javascriptnode.jsangularjsexpress

提问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.jsfile 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.htmlfile, 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.jsso 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.allstatement 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'
    }

 }

})