web-dev-qa-db-ja.com

Angular Node.jsを使用したHTML5モードでのルーティング

これには他にも答えがあることは知っていますが、注意点があるようです。

これによりリダイレクトが発生します これはMixpanelを使用するフロントエンドアプリにとって致命的であり、Mixpanelを2回ロードすると、ブラウザーで最大呼び出しスタックサイズ超過エラーが発生します。

これはsendFile を使用していますが、個人的には仕事に就けません。それを診断しようとすると、express.static()を使用することをお勧めします。

現在、私のコードは次のようになっています。

home.js-いくつかのルート。最後のルートはフロントエンドサイトを目的としています。

_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-node/expressの構成

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

いくつかの詳細情報

express.static()を使用しようとしていることがわかる理由は、res.sendfile()を使用すると、問題が発生するためです このように コンソールに_Unexpected token '<'_。残念ながら、回答は正確な修正を指定しておらず、問題を修正したと言っているが回答を共有していない質問者も指定していません。

私の試行錯誤の中で、私はこのように表現するためにさらにいくつかを追加しました

_.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' ) )
_

そして私の_home.js_ルートファイルにこれを追加しました

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

また、ブラウザでは、すべてのファイルが読み込まれていることがわかりますが、上記の_<_エラーがあります。更新を行うと、この_/*/_ルートが何百回も呼び出されているので、.use( '...', ... )構成は無視されていると思います。


以下は、Jonasからリクエストされた別の例です。

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

.use( '/', require( './routes/home.js' ) )行を使用せずに同じことを行って問題を絞り込みましたが、同じ結果です。 URLに_#_が含まれている場合、ページは読み込まれますが、ブラウザは_#_を削除します(これまでのところ良好です)。しかし、更新を押すか、URLを手動でsans-hashbangに入力すると、_Cannot GET /home/splash_のようなエラーが発生します。ここで、_/home/splash_は私が行くパスです。

18
Noah

Expressミドルウェアを間違った方法で使用している可能性があります。 documentation を見ると、たとえば次のコードがわかります

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

indexPath + '/images'フォルダーの下にあるファイルを次のようなURLで提供します。

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

それはあなたがそれがすることを期待することですか?

私の提案はから変更することです

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

.use(express.static( indexPath ))

ドキュメントによると、ルートパス(別名)からindexPathフォルダーの下にあるすべての静的ファイルを提供するためです。プレフィックスなし。

あなたがこれまでに与えたインプットについて私が助けることができるのはそれだけだと思います。それでもうまくいかない場合は、自分で再現するために使用できる小さなコード例を共有してください。

更新

OK。私はそれの簡単な例を作成しようとしました。私はそれを次のように機能させました。私のディレクトリ構造は次のようなものです。

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

index.jsはノードサーバーです。ルーティングの順序に注意してください。また、角度を通過してはならない他のサーバールートを追加する方法を明確にするために、いくつかの/home/loginの例を追加しました。

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はとても簡単です。

<!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はコンテンツを追加するだけです。重要なのは/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は実際には無関係です

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

main.jsはコアを実行していますangular html5の作業

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++;
        };
    });
12
Jonas

の代わりに:

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

行う

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

ルートファイルの最後に置いてください。

5
Paweł Smołka

AJAXリクエストに問題があるようです。
私は通常、次のようにルートを設定します。

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

ディレクティブで_templateUrl: "/templates/home.html"_を使用してフロントエンドで呼び出しを行います

または$http.get("/images").success(...).error(...) $ httpを使用します。

TemplateUrlの場合、アプリはパブリックディレクトリに移動し、次にパステンプレートに移動して、htmlファイルを提供します。 $ httpの場合、アプリがパブリックディレクトリをチェックし、画像パスが表示されないようにルートを指定しているため、ルーターに移動します。ルーターにはrouter.get("/images", function (req, res, next) { res.sendFile(...);またはres.send({(data)}) })があり、必要なファイルをフロントエンドに送り返し、そこで成功ハンドラーでキャッチします。

0
Isaac Madwed