Подтвердить что ты не робот

Используя AngularJS html5mode с nodeJS и Express

Я использую nodeJS-сервер с Express для обслуживания моего приложения AngularJS. Все это прекрасно работает, когда я использую маршруты angularJS по умолчанию (hashbangs), но теперь я пытаюсь активировать режим html5.

Я активирую html5mode следующим образом:

$locationProvider.html5Mode(true).hashPrefix('!');

И вот что выглядит мой файл 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
    }));
});

Однако теперь это все запросы, как мой index.html, и поэтому я получаю следующую ошибку от requireJS:

Uncaught SyntaxError: Unexpected token < 

Я попытался добавить следующее к моему 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"));

но все равно не повезло.

Я также попытался заменить оператор 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');
});

но это тоже не сработало. Что я могу сделать, чтобы заставить angularJS html5mode работать с nodeJS и Express? Спасибо.

4b9b3361

Ответ 1

Ваше первоначальное исправление (объявление статических промежуточных обработчиков для определенных префиксов) должно работать нормально, но вам нужно убедиться, что они объявлены перед любыми другими маршрутами (и 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("/*", ...);

Кроме того, вам нужно убедиться, что префиксные статические обработчики фактически объявлены в порядке (правильный путь), иначе они не смогут найти какие-либо запрошенные файлы, и запросы передадут цепочку промежуточного программного обеспечения и в конечном итоге будут обработаны обработчик catch-all (должен быть достаточно прост, чтобы проверить, комментируя обработчик catch-all и посмотрите, работают ли какие-либо запросы JS/CSS/...).

Ответ 2

Настройте сервер Express 4 как:

app.use(express.static(__dirname + '/public'));

app.get('/*', function(req, res){
    res.sendFile(__dirname + '/public/index.html');
});

и angular как:

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

Ответ 3

Я работаю над веб-приложением, использующим Angularjs и Requirejs на клиенте, с Nodejs на сервере.

Вот пример кода, который покажет вам, как я его настроил.

Обратите внимание, что в этом примере показан хэш-код, но вы можете легко изменить его, изменив функцию промежуточного программного обеспечения и angular конфигурацию

Функция промежуточного программного обеспечения

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

Конфигурация маршрута сервера

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

Конфигурация клиентского маршрута

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

Файл загрузчика

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

Файл маршрутов

define(function(){
  return {
     {
        name        : "type",
        url         : "/",
        templateUrl : "/requirements/type",
        view        : 'services'
    }

 }

})