4

我昨天在stackoverflow上发布了一个问题(刷新时不包含css和javascript),询问为什么我刷新网页后css和javascript没有包含在我的网页上并发现它是由html5mode引起的,所以从昨天开始,我一直在寻找这个问题的解决方案,但我无法真正得到答案。

我的文件夹结构

在此处输入图像描述

应用程序.js

var express = require('express')
  , routes = require('./routes')
  , user = require('./routes/user')
  , http = require('http')
  , path = require('path')
  , mongoose = require('mongoose');

var app = module.exports=express();
// all environments
app.set('port', process.env.PORT || 3000);
app.set('views', __dirname + '/public/views');
app.set('view engine', 'ejs');
app.use(express.cookieParser());
app.use(express.favicon());
app.use(express.logger('dev'));
app.use(express.bodyParser());
app.use(express.methodOverride());
app.use(express.static(path.join(__dirname, 'public')));
app.use(app.router);
app.use(function(request, response)
{
    console.log("catch all");
    writeFile("/public/views/master.ejs", request, response);
});
// development only
if ('development' == app.get('env')) {
  app.use(express.errorHandler());
}
app.use(function (req,res) {
 res.status(404).render('error', {
                url: req.originalUrl
            });
});

app.get('/', routes.index);
app.get('/:name', routes.view);
app.get('*', routes.risk);

http.createServer(app).listen(app.get('port'), function(){
  console.log('Express server listening on port ' + app.get('port'));
});

index.js

exports.index = function(req, res){
  res.render('master', { title: 'Hello World' });
};
exports.view = function (req, res) {
  var name = req.params.name;
  res.render(name);
};
exports.risk = function(req, res){
  res.sendfile(__dirname + "/public/views/master.ejs");
};

对于exports.risk,我试图让expressJs 在渲染其他母版页之前先渲染母版页,但它不起作用。

角Js

var SymSal = angular.module('SymSal',[]).
 config(['$routeProvider', '$locationProvider', function($routeProvider, $locationProvider) {
    $routeProvider.
      when('/', {
        templateUrl: 'main.ejs',
        controller: 'IndexCtrl'
      }).
      when('/login',{
        templateUrl: 'login.ejs',
        controller: 'IndexCtrl'
      }).
      when('/register',{
        templateUrl: 'register.ejs',
        controller: 'IndexCtrl'
      }).
      when('/about',{
        templateUrl: 'about.ejs',
        controller: 'IndexCtrl'
      }).
      otherwise({
        templateUrl: 'error.ejs'

      });
    $locationProvider.html5Mode(true);
  }]);

 SymSal.controller('IndexCtrl',function(){

 })

感谢您的帮助,谢谢!

4

2 回答 2

5

对于exports.risk,我试图让expressJs 在渲染其他母版页之前先渲染母版页,但它不起作用。

路由按顺序匹配:

app.get('/', routes.index);
app.get('/:name', routes.view);
app.get('*', routes.risk);

如果路由匹配 '/' 渲染 routes.index。如果路由不匹配'/',检查它是否匹配'/:name'(例如/login,/register)并渲染routes.view。如果路由不匹配 '/' 和 '/:name'(例如路由类似于 /user/1)routes.risk 将被渲染。

要首先快速渲染母版页,您需要删除 '/' 和 '/:name' 的路由匹配器,并保留将匹配每个路由的通用匹配器 ('*')。

现在无论您提供什么 url,服务器都会发回母版页。如果您调用 localhost:3000/login,服务器将发回母版页(与您调用 localhost:3000 相同的页面)。Angular 会看到一个路径(/login)被指定并且会调用适当的 $routeProvider.when() 函数。

要处理 api 调用(例如从 db 获取数据,将数据保存到 db),您需要为此指定一个路由匹配器并将其放在通用匹配器('*')之上:

app.get('/api', routes.api);

值得一提的是,您没有在 $routeProvider.when() 中使用“/api”。

剩下的是对静态文件的正确处理:记住每个 url 都由通用匹配器 ('*') 处理。因此静态文件会使用错误的 MIME 类型进行渲染。要解决此问题,您需要使所有静态文件都可以在特定路径下访问,例如“/static”。只需更新

app.use(express.static(path.join(__dirname, 'public')));

app.use('/static', express.static(path.join(__dirname, 'public')));

您需要更新母版页中的所有路径以匹配新模式:“/js/angular.js”现在是“/static/js/angular.js”

于 2013-10-26T20:59:40.637 回答
2

感谢@bekite 提供了一个合理解决方案的基础。在他最初的解决方案的基础上,我发现以下内容对自己来说更干净一些,并且它避免了需要更新和维护所有带有/static前缀的路径。请注意,这app.get('*', routes.risk)对我不起作用(Express v3.4.4),但是使用正则表达式可以:

...
app.use(app.router);
app.use(express.static(path.join(__dirname, 'app')));

// Express routes - ensure these are not defined in Angular's app.js $routeProvider:
app.get('/api', routes.api);

/**
 * ANGULAR APP ROUTING
 * --------------------
 * These routes will fallback to Angular for resolution of any uri:
 * Note that the * wildcard will not work, hence the alternate regex
 * It is crucial that 'static' assets never be referenced with a leading
 * forward slash '/', else they'll match this rule and 404's will occur
 */
//app.get('*', routes.risk);
app.get('/[a-z]{0,100}', routes.risk);

////
// alternatively:
//
// app.get('/[a-z]{0,100}', function(req, res) {
//     res.sendfile('app/index.html', {title: 'Default Title', stuff: 'More stuff to send to angular'}
// });
...

根据@bekite,Angular 路径被传递到通用路由(如果需要,它可以提供进一步的分支),并由 Angular $routeProvider 捕获。快速路径使用前缀捕获并/api根据需要在服务器端进行处理。

于 2013-12-11T01:11:34.227 回答