【问题标题】:Angular routing in HTML5mode with Node.js使用 Node.js 在 HTML5 模式下进行角度路由
【发布时间】:2015-09-28 09:59:07
【问题描述】:

我知道对此还有其他答案,但它们似乎有一些警告。

This one causes a redirect,这对于我使用 Mixpanel 的前端应用程序来说可能是致命的,并且双重加载 Mixpanel 会在浏览器中出现 Maximum Call Stack Size Exceeded 错误。

This one uses 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 - 配置节点/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() 时,我遇到了问题like this one,控制台显示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 是我要去的任何路径。

【问题讨论】:

  • 如何为此添加赏金?已经4天了……
  • 我不是 express 方面的专家,但我从来没有看到有人在关注UI-Router FAQ 中的示例时出错,这表明使用app.all 而不是router.get。跨度>
  • 您检查传递给express.static 的路径是否有效? indexPath 的值是多少?
  • 简单地使 var app = express(); app.configure(function() { ... app.use(express.static(__dirname + '/public')); ... }
  • @PawełSmołka 我不认为 app.configure 是 express 4 的一部分。

标签: javascript angularjs node.js express angular-ui-router


【解决方案1】:

您可能以错误的方式使用 express 中间件。例如,查看documentation 告诉我以下代码

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

使用此类 URL 提供文件夹 indexPath + '/images' 下的任何文件:

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 文件夹下的所有静态文件,也就是。没有前缀。

我认为这就是我迄今为止所能提供的所有帮助。如果这不能解决问题,也许您可​​以分享一些小代码示例,我可以自己使用它来重现它。

更新

好的。我试图创建一个简单的例子。我通过以下方式使其工作。 我的目录结构是这样的:

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

index.js 是节点服务器。注意路由的顺序。我还添加了一些 /home/login 示例,以明确如何添加不应通过 angular 的其他服务器路由。

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

【讨论】:

  • 当我在 Angular 中使用带有 HTML5 模式的 express.static 时,刷新或手动输入 URL 后出现错误 Cannot GET [path to page]。如果我将# 添加回 URL,我可以查看该页面并且 # 将被删除。
  • @Noah 你能举个例子吗?
  • 你是在告诉我你确定.use(express.static( indexPath )) 支持 HTML5 吗?因为好像没有。它一直有效,直到我点击刷新,然后它说Cannot GET /home/splash。如果我将 # 放回 URL 中,它会加载并删除 #,但再次刷新会再次出现错误。
  • 我在上面附加了一个例子。
  • 我认为问题在于我没有把.use(express.static('public'))放在第一,我总是把它放在最后。
【解决方案2】:

代替:

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

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

只需将其保留在路线文件的末尾即可。

【讨论】:

  • 我在使用路径时得到Cannot GET /home/login,在路径中使用# 时得到Cannot GET /
【解决方案3】:

您的 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)}) }) 将我需要的文件发送回前端,并在成功处理程序中捕获。

【讨论】:

  • 我在前端使用$http,并像你解释的那样声明templateUrl。你在用html5Mode吗?你能确认它适用于 Express 吗?
  • 我正在使用 angular 和 express 设置。在静态路由器中需要提供相对路径(即path.join(__dirname, "public")
猜你喜欢
  • 1970-01-01
  • 2016-04-07
  • 2016-03-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-10-31
  • 2022-01-03
  • 2014-11-03
相关资源
最近更新 更多