2015-07-09 12 views
18

So che ci sono altre risposte a questo, ma sembrano avere avvertenze.Instradamento angolare in HTML5mode con Node.js

This one causes a redirect, che può essere fatale per la mia app front-end che utilizza Mixpanel, e un doppio carico di Mixpanel sarà un errore di dimensione massima Stack di chiamate superato nel browser.

This one uses sendFile che personalmente non riesco a mettermi al lavoro. Cercando di diagnosticare ciò, mi viene solo consigliato di usare express.static().

Attualmente il mio codice simile a questo:

home.js - Alcuni itinerari, l'ultimo destinato ad essere il sito di front-end.

var indexPath = path.resolve(__dirname, '../' + process.env.PUBLIC_FOLDER) 

router.get('/:user/:stream/:slug', function(req, res, next) { 

    if (req.headers['user-agent'].indexOf('facebook') != -1) { 
     // stuff to handle the Facebook crawler 
    } else return next() 
}) 

router.get('/*', function(req, res) { 
    express.static(indexPath) 
}) 

server.js - Configurazione di node/esprimere

app = express(); 

app 
    .use(morgan('dev')) 
    .use(bodyParser.urlencoded({ limit: '50mb', extended: true })) 
    .use(bodyParser.json({ limit: '50mb' })) 
    .use('/api', require('./routes/usersRoute.js')) 
    .use('/', require('./routes/home')) 
    .on('error', function(error){ 
     console.log("Error: " + hostNames[i] + "\n" + error.message) 
     console.log(error.stack) 
    }) 

http 
    .createServer(app).listen(process.env.PORT) 
    .on('error', function(error){ 
     console.log("Error: " + hostNames[i] + "\n" + error.message) 
     console.log(error.stack) 
    }) 

qualche info in più

La ragione per cui si può vedere che sto cercando di utilizzare express.static() è perché quando uso res.sendfile() Ottengo un problema like this one dove la console dice Unexpected token '<'. Sfortunatamente la risposta non specifica una correzione esatta e nemmeno l'interrogante che dice di aver risolto il problema ma non ha condiviso una risposta.

Nella mia prova ed errore ho aggiunto un po 'di più per esprimere, come questo

.use('/app/app.js', express.static(indexPath + '/app/app.js')) 
.use('/app/views', express.static(indexPath + '/app/views')) 
.use('/app/controllers', express.static(indexPath + '/app/views')) 
.use('/app/directives', express.static(indexPath + '/app/views')) 
.use('/app/vendor', express.static(indexPath + '/app/vendor')) 
.use('/js', express.static(indexPath + '/js')) 
.use('/css', express.static(indexPath + '/css')) 
.use('/fonts', express.static(indexPath + '/fonts')) 
.use('/images', express.static(indexPath + '/images')) 
.use('/api', require('./routes/usersRoute.js')) 
.all('/*', require('./routes/home')) 

E nei miei home.js percorsi file aggiunti questa

router.get('/*', function (req, res) { 
    res.status(200).set({ 'content-type': 'text/html; charset=utf-8' }) 
    .sendfile(indexPath + '/index.html') 
}) 

E nel browser posso vedere tutto il mio i file si stanno caricando, ma con l'errore < sopra. Vedo che questa route /*/ viene chiamata centinaia di volte quando eseguo un aggiornamento, quindi penso che le configurazioni .use('...', ...) vengano ignorate.


Ecco un altro esempio richiesto da Jonas di seguito.

var indexPath = path.resolve(__dirname, process.env.PUBLIC_FOLDER) 

mongoose.connect(process.env.MONGOLAB_URI) 

app = express(); 

app 
    .use(morgan('dev')) 
    .use(bodyParser.urlencoded({ limit: '50mb', extended: true })) 
    .use(bodyParser.json({ limit: '50mb' })) 
    .use('/api', require('./routes/usersRoute.js')) 
    .use('/', require('./routes/home.js')) 
    .use(express.static(indexPath)) 
    .on('error', function(error){ 
     console.log("Error: " + hostNames[i] + "\n" + error.message) 
     console.log(error.stack) 
    }) 

ho anche fatto lo stesso senza la linea .use('/', require('./routes/home.js')) per provare a restringere alcun problema, ma è lo stesso risultato. La pagina verrà caricata se ho l'# nell'URL, ma il browser rimuoverà il # (fin qui tutto bene). Ma se premo refresh, o inserisco l'URL manualmente, sans-hashbang, darà un errore come Cannot GET /home/splash, dove /home/splash è il percorso che sto per fare.

+0

Come si aggiunge una taglia a questo? Sono passati 4 giorni ... – Noah

+0

Non sono un esperto di express, ma non ho mai visto nessuno sbagliare quando ho seguito gli esempi nelle [FAQ UI-Router] (https://github.com/angular-ui/ui-router/wiki/Frequently-Asked-Questions), che mostra l'uso di 'app.all' piuttosto che' router.get'. – Claies

+0

Hai controllato che i percorsi passati a 'express.static' siano validi? Qual è il valore di 'indexPath'? – manji

risposta

12

È possibile che si stia utilizzando il middleware Express nel modo sbagliato. Guardando il documentation mi dice per esempio che il codice seguente

.use('/images', express.static(indexPath + '/images')) 

Serve un qualsiasi file sotto la cartella indexPath + '/images' con tali URL:

http://localhost:3000/images/kitten.jpg 
http://localhost:3000/images/logo.png 
http://localhost:3000/images/whatever.jpg 

è quello che ci si aspetta che faccia?

Il mio suggerimento è quello di cambiare da

.use('/', require('./routes/home')) 

a

.use(express.static(indexPath)) 

Poiché in base alla documentazione, che servirà tutti i file statici nella cartella indexPath dal percorso principale, alias. senza prefisso.

Penso che sia tutto ciò che posso aiutare con l'input che hai dato finora. Se questo non funziona, forse puoi condividere qualche piccolo esempio di codice che posso usare per riprodurlo da solo.

UPDATE

Ok. Ho provato a creare un semplice esempio di esso. L'ho fatto funzionare nel modo seguente. La mia struttura di directory è come questo:

|- index.js 
|- public/ 
|---- index.html 
|---- test.html 
|---- main.js 
|---- angular.js 
|---- angular-route.js 

index.js è il server del nodo. Prestare attenzione all'ordine del routing. Ho anche aggiunto alcuni esempi di /home/login per chiarire come aggiungere altre route del server che non dovrebbero passare per angolare.

var http = require('http'); 
var express = require('express'); 
var app = express(); 

app 
    .use(express.static('public')) 
    .get('/home/login', function (req, res) { 
     console.log('Login request'); 
     res.status(200).send('Login from server.'); 
    }) 
    .all('/*', function (req, res) { 
     console.log('All'); 
     res 
      .status(200) 
      .set({ 'content-type': 'text/html; charset=utf-8' }) 
      .sendfile('public/index.html'); 
    }) 
    .on('error', function(error){ 
     console.log("Error: \n" + error.message); 
     console.log(error.stack); 
    }); 

http 
    .createServer(app).listen(8080) 
    .on('error', function(error){ 
     console.log("Error: \n" + error.message); 
     console.log(error.stack); 
    }); 

console.log('Serving app on port 8080'); 

index.html è piuttosto semplice.

<!doctype html> 
<html> 
<head> 
    <title>Angular HTML5 express test</title> 
    <script type="text/javascript" src="angular.js"></script> 
    <script type="text/javascript" src="angular-route.js"></script> 
    <script type="text/javascript" src="main.js"> 
    </script> 
</head> 
<body ng-app="app"> 
    <div ng-view></div> 
</body> 
</html> 

main.html aggiunge solo alcuni contenuti. Importante è il link per /test

<div> 
    <h1>This is just a {{val}}</h1> 
    <button ng-click="clicked()">Click me!</button> 
    <span>You clicked {{counter}} times</span> 
    <a href="/test">test me!</a> 
</div> 

test.html è in realtà irrilevante

<div> 
    <h4>What a beautiful day to test HTML5</h4> 
</div> 

main.js sta facendo il nucleo di lavoro HTML5 angolare

angular.module('app', ['ngRoute']) 
    .config(function($locationProvider) { 
     $locationProvider 
      .html5Mode({ 
       enabled: true, // set HTML5 mode 
       requireBase: false // I removed this to keep it simple, but you can set your own base url 
      }); 
    }) 
    .config(function($routeProvider) { 
     $routeProvider 
      .when('/test', {templateUrl: 'test.html', controller: function() { 
       console.log('On /test.'); 
      }}) 
      .when('/', {templateUrl: 'main.html', controller: 'MyTestCtrl'}) 
      .otherwise('/'); 
    }) 
    .controller('MyTestCtrl', function ($scope) { 
     self = $scope; 
     self.val = 'TeSt'; 
     self.counter = 0; 
     var self = self; 
     self.clicked = function() { 
      self.counter++; 
     }; 
    }); 
+0

Quando uso 'express.static' con la modalità HTML5 in Angular, ottengo il errore 'Impossibile ottenere [percorso alla pagina]' dopo aver aggiornato o inserito manualmente un URL. Se aggiungo il '' # all'URL, posso visualizzare la pagina e il # sarà stato rimosso. – Noah

+0

@Noah Puoi creare un esempio? – Jonas

+0

Mi stai dicendo che sei sicuro che '.use (express.static (indexPath))' supporta HTML5? Perché non sembra. Funziona fino a quando non tocchi refresh, th it dice "Impossibile ottenere/home/splash". Se rimetto il '# indietro nell'URL, carica e rimuove' # ', ma l'aggiornamento restituisce nuovamente l'errore. – Noah

5

invece di:

router.get('/*', function(req, res) { 
    express.static(indexPath) 
}) 

fare

router.get('/:anyreq', function(req, res) { 
    express.static(indexPath) 
}) 

basta tenere alla fine del file percorsi.

+0

Viene visualizzato 'Can not GET/home/login' quando si utilizza un percorso e' Can not GET/'quando si utilizza un' # nel percorso. – Noah

0

Sembra che potrebbe esserci un problema con le richieste AJAX.
Io di solito le mie vie come questo:

app.use(express.static(path.join(__dirname, "./public"))); app.use("/", require(path.join(__dirname, "./routes")));

ed effettuare chiamate sul front-end con templateUrl: "/templates/home.html" in una direttiva

o $http.get("/images").success(...).error(...) utilizzando $ http.

Nel caso templateUrl l'applicazione entra nella directory pubblica, quindi nei modelli di percorso e nel servizio del file html. Nel caso $ http sto specificando un percorso in modo che l'app controlli la directory pubblica, non veda il percorso di un'immagine e così si trasferisca al router. Nel router ho un router.get("/images", function (req, res, next) { res.sendFile(...); o o res.send({(data)}) }) che invia il file di cui ho bisogno al front-end in cui è catturato nel gestore di successo.

+0

Sto usando '$ http' sul front-end e dichiaro' templateUrl' come mi spieghi Stai usando 'html5Mode'? Puoi confermare che funziona con Express? – Noah

+0

Sto usando angolare ed express con quella configurazione.Nel router statico devi fornire il percorso relativo (cioè' path. join (__ dirname, "public") ') –

Problemi correlati