web-dev-qa-db-ja.com

Expressルーティングと組み合わせたAngular2ルーティング?

URL経由でアクセスすると、angular2アプリのルートが機能しません...代わりにExpressがエラーページをレンダリングしています。

したがって、静的コンテンツとその他の静的リソースを提供する1つのルート(/docs)がありますが、/はangular)によって管理されるindex.htmlにルーティングされます。 = 2.したがって、アプリケーションルートを開き、さまざまなルーターリンクをクリックすると、ルート(/tutorial/chapter/1など)にアクセスできます。ただし、エクスプレスアプリに登録されたルートではないため、ページを更新すると、 404。

ブラウザにhttp://localhost:3000/tutorial/chapter/1と入力して、そのページを取得できるようにしたいと思います。未定義のすべてのルートをangularにルーティングするようにexpressを設定し、angularが404を処理するようにするにはどうすればよいですか?

これが私のapp.jsです:

var app = express();

// html view engine setup
app.set('views', path.join(__dirname, '/ng2/views'));
app.engine('html', require('jade').renderFile);
app.set('view engine', 'html');

app.use(express.static('ng2/views'));
app.use(express.static('ng2/public'));

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

// uncomment after placing your favicon in /public
app.use(favicon(path.join(__dirname, 'ng2/public', 'favicon.png')));
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(cookieParser());

//all static assetes for hexo content

app.use('/docs', serveStatic('features/docs/public', { 'index': ['index.html', 'index.htm'] }));

app.use('/', routes);

// catch 404 and forward to error handler
app.use(function (req, res, next) {
  var err = new Error('Not Found');
  err.status = 404;
  next(err);
});


module.exports = app;

あなたは完全なレポを見ることができます ここ

ルートミドルウェアdefは次のとおりです。

var express = require('express');
var router = express.Router();

/* GET home page. */
router.get('/', function(req, res, next) {
  res.render('index', { title: 'Express' });
});


module.exports = router;
12
George Edwards

app.js

順序が重要であり、新しいコードが複数の場所に挿入されるため、ファイル全体が含まれます。 // JS -で始まるコメントを探します

var express = require('express');
var path = require('path');
var favicon = require('serve-favicon');
var logger = require('morgan');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');
var serveStatic = require('serve-static')
var file = require('./features/prepareTutorial');
var routes = require('./ng2/routes/index');

var app = express();

// html view engine setup
app.set('views', path.join(__dirname, '/ng2/views'));
app.engine('html', require('jade').renderFile);
app.set('view engine', 'html');

app.use(express.static('ng2/views'));
app.use(express.static('ng2/public'));

app.use('/node_modules', express.static(__dirname + '/node_modules'));
app.use('/persist', express.static(__dirname + '/persist'));

// JS - Add /app
app.use('/app', express.static(__dirname + '/ng2/views/app'));

// I have to comment this line because it failed
//file.processTutorial(); //generate html rendered patches for tutorial steps
//file.genGit(); //generate git SHA
file.processChapters();

// uncomment after placing your favicon in /public
app.use(favicon(path.join(__dirname, 'ng2/public', 'favicon.png')));
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(cookieParser());

//all static assetes for hexo content

app.use('/docs', serveStatic('features/docs/public', { 'index': ['index.html', 'index.htm'] }));
//app.use(subdomain('docs', express.static('docs/public')));
app.use('/script', serveStatic('features/docs/public/script'));
app.use('/style', serveStatic('features/docs/public/style'));
app.use('/images', serveStatic('features/docs/public/images'));
app.use('/diff', serveStatic('features/tutorial/diffs'));
app.use('/git', serveStatic('features/git'));
app.use('/chapter', serveStatic('ng2/views/app/tutorial/chapter/chapters'));
app.use('/img', serveStatic('features/docs/source/img'));

app.use('/config', serveStatic('ng2/config'));

app.use('/', routes);

// JS - /tutorial static
//app.use('/tutorial', express.static('ng2/views/app/tutorial'));
// JS - /tutorial/chapter/* send index file 
app.all(/^\/tutorial$/, (req, res) => {
  res.redirect('/tutorial/');
});
app.use('/tutorial/', (req, res) => {
  res.sendFile(__dirname + '/ng2/views/index.html');
});

// catch 404 and forward to error handler
app.use(function (req, res, next) {
  var err = new Error('Not Found');
  err.status = 404;
  next(err);
});

// error handlers

// development error handler
// will print stacktrace
if (app.get('env') === 'development') {
  app.use(function (err, req, res, next) {
    res.status(err.status || 500);
    res.render('error', {
      message: err.message,
      error: err
    });
  });
}

// production error handler
// no stacktraces leaked to user
app.use(function (err, req, res, next) {
  res.status(err.status || 500);
  res.render('error', {
    message: err.message,
    error: {}
  });
});


module.exports = app;

ng2/config/systemjs.config.js&ng2/public/config/systemjs.config.js

絶対パスを使用する

これが主な問題です。相対パスを使用すると、ブラウザはtutorial/chapter/2/app/*tutorial/chapter/2/node_modules/*などのファイルを要求し、アプリは完全に機能しなくなります。

// snip ...
var map = {
    'app':                        '/app', // 'dist',
    '@angular':                   '/node_modules/@angular',
    'angular2-in-memory-web-api': '/node_modules/angular2-in-memory-web-api',
    'rxjs':                       '/node_modules/rxjs'
  };
// snip ...

ng2/views/index.html

絶対パスを使用する

これはページの読み込みを停止しませんが、混乱します。

// snip ...
<link rel="stylesheet" href="/stylesheets/style.css">
// snip ...
5
John Siu

Angular 2は、リクエストURLとは関係なく、フロントエンドが返されることを前提としています。この仮定は、Push stateと呼ばれる最新のブラウザが実装する機能に基づいています。ブラウザの最先端以外のものをサポートしたい場合は、3つのオプションがあります。

  • 推奨:APIサーバーをクライアントから分離します。
    クライアントをexample.orgに配置し、エクスプレスバックエンドをapi.example.orgに配置すると、Angularがtrueと見なされることを実行できます。デプロイすることもできます。独立しており、クライアントは静的ホストまたはCDNに存在できます。ただし、これにはCORSをセットアップする必要があります。

  • キャッチオールエクスプレスルート
    ExpressのすべてのルートがNG2で設定したルートと異なることを確認し、キャッチオールハンドラーを作成します。このようなものをルート/ミドルウェアの最後、ただし404ハンドラーの前に配置してください!

    app.use(function(req, res, next) {
      res.sendFile("index.html");
    })
    
  • ルーターにはレガシーブラウザのURLスタイルを使用します。
    NG2ルーターにルートにハッシュを使用させることができます。チェック ここ

12
Sascha

app.use('/', routes);の代わりに、常にindex.htmlを提供するミドルウェアを登録します。ただし、これにより、アプリがindex.htmlルート内でも/docsを返す可能性があることに注意してください。

インデックスページをレンダリングするミドルウェアを使用するだけです。

app.use(routes);

routesミドルウェア自体が、/パスだけでなく、常にページをレンダリングすることを確認してください。

var express = require('express');

/* render home page. */
var router = function(req, res, next) {
  res.render('index', { title: 'Express' });
};

module.exports = router;

これを404ハンドラーから削除します(自動である必要があります)

// catch 404 and forward to error handler
app.use(function (req, res, next) {
  var err = new Error('Not Found');
  err.status = 404;
  next(err);
});

そして、node_modulesルートを次のように変更します(SystemJSは解決中に404応答に依存しているため)。

var modules = express.Router();

modules.use(express.static(__dirname + '/node_modules'));
modules.use(function(req, res, next) {
    // Missing files inside node_modules must return 404
    // for the module loader to work
    res.sendStatus(404);
});


app.use('/node_modules', modules);  
1
Tamas Hegedus