2013-10-26 32 views
4

我昨天發佈了一個問題在stackoverflow(css and javascript didn't include on refresh)問我關於爲什麼css和javascript沒有包括在我的網頁上後,我刷新網頁,並找到它由html5mode引起的,所以我從昨天起一直在尋找這個問題的解決方案,但我無法真正得到答案。如何使html5mode使用expressJs路由工作Angularjs

我的文件夾結構

enter image description here

app.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渲染主頁面之前呈現其他,但它不工作。

angularJs

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(){ 

}) 

您的幫助表示讚賞,謝謝!

+0

[css和javascript不包括在刷新上]的可能重複(http://stackoverflow.com/questions/19561271/css-and-javascript-didnt-include-on-refresh) – lort

回答

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'的路由匹配器,並保留匹配每條路由的通用匹配器('*')。

現在無論您提供什麼網址,服務器都會發回主頁面。 如果您調用localhost:3000/login,服務器將發回主頁面(如果您要調用localhost:3000,則返回相同的頁面)。 Angular會看到指定了一個路徑(/ login),並會調用相應的$ routeProvider.when()函數。

要處理的API調用(如獲取從數據庫中的數據,將數據保存到數據庫),你需要指定一個路由匹配了這一點,並把它放在通用匹配以上(「*」):

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」現在「/靜態/ JS/angular.js'

+0

嘿貝基特謝謝你的回覆!,我已經嘗試過你的解決方案,但我的angular.js似乎有一些錯誤,當我開始我的應用程序的網頁都掛在那裏,並繼續加載可能我知道是什麼原因導致這個問題? –

+1

我創建了一個plunker:http://plnkr.co/edit/V8OWrMrnXM3j76WZ4TVc?p=catalogue。這應該呈現一個HTML頁面。我使用玉模板,你使用ejs。所以你需要編輯views/index.jade。 – bekite

+0

是的,我認爲我在expressjs的路徑是正確的,但它看起來像我的angular.js是問題,如果我刪除angular.js它工作完美,但與angular.js基本佈局存在,但它無法獲取內容從main.ejs和網頁不斷加載,不能新鮮點擊F12 –

2

感謝@bekite爲合理解決方案的基礎。在他最初的解決方案的基礎上,我發現了以下一點清潔劑,它避免了需要使用前綴/static更新和維護所有路徑。需要注意的是app.get('*', routes.risk)並沒有爲我(快遞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 $ routeProvider捕獲。 Express路徑被/api前綴捕獲,並根據需要處理服務器端。

+1

我有'app.get('/ *''但是當我改變到'app.get('/ [a-z0-9 \ /] {0,100}'')時,它和預期一樣工作。你明白爲什麼它是這樣的? – Cotten