简体   繁体   English

Node Express服务器深度链接不适用于AngularJS html5Mode

[英]Node Express server deep linking not working with AngularJS html5Mode

( Update : I solved the problem. Just look at the end of the question) 更新 :我解决了这个问题。只看问题的结尾)

I am running with this problem that seems trivial to me, but I am very frustrated because I am not able to figure it out: 我正在处理这个似乎对我来说微不足道的问题,但是我很沮丧,因为我无法弄清楚:

I scaffolded an Angular application using yeoman generator-angular . 我使用yeoman generator-angular搭建了Angular应用程序。 I need to use the html5mode of Angular to get rid of the hashtag (please, see app.js below). 我需要使用Angular的html5mode摆脱#标签(请参阅下面的app.js )。 I am using a node express server (see server.js ) to run the app built with grunt build . 我正在使用节点快速服务器(请参阅server.js )运行使用grunt build的应用程序。 As required, I added the option in the server to redirect to index.html when accessing the app from any specific route. 根据需要,我在服务器中添加了从任何特定路径访问应用程序时重定向到index.html的选项。 It works with one level of "routing", ie, localhost:8080/research , but it does not work for two "levels" or more, ie, localhost:8080/research/human . 它只能在一个“路由”级别(即localhost:8080/research ,但不适用于两个或更高级别的“路由”(即localhost:8080/research/human In this case, when refreshing the browser, I get this error: 在这种情况下,刷新浏览器时会出现以下错误:

The stylesheet http://localhost:8080/research/styles/vendor.8089f103.css was not loaded because its MIME type, "text/html", is not "text/css". human
The stylesheet http://localhost:8080/research/styles/main.e7eff4cf.css was not loaded because its MIME type, "text/html", is not "text/css". human
SyntaxError: expected expression, got '<' vendor.01f538ae.js:1:0
SyntaxError: expected expression, got '<'

I have searched everywhere, I have tried all sort of options, but I am not able to fix it. 我到处搜索过,尝试过各种选项,但无法修复。 I would really appreciate some help, please! 我真的很感谢您的帮助!

app.js app.js

angular
  .module('testAngularApp', [
    'ngRoute',
    'ngTouch',
    'ngAnimate',
    'ngSanitize',
    'angulartics'
  ])
  .config(function ($routeProvider, $locationProvider) {

    $locationProvider.html5Mode(true);

    $routeProvider
      .when('/', {
        templateUrl: 'views/mainFrontpage.html',
        controller: 'MainFrontpageController'
      })
      .when('/research', {
        templateUrl: 'views/research.html',
        controller: 'ResearchController'
      })
      .when('/research/human', {
        templateUrl: 'views/research-human.html',
        controller: 'ResearchController'
      })
      .when('/research/fly', {
        templateUrl: 'views/research-fly.html',
        controller: 'ResearchController'
      })
      .otherwise ({
        templateUrl: 'views/notyetready.html',
      }); 
  });

server.js server.js

'use strict';

var express = require('express');
var path = require('path');
var morgan = require('morgan');
var fs = require('fs');

var currentDir = process.cwd();

var app = express();

var staticStats = fs.statSync( currentDir + '/dist');

if (staticStats.isDirectory()) {
    app.use('/', express.static(currentDir + '/dist'));

    // Here I have tried many different combinations
    app.use("/styles", express.static(__dirname + "dist/styles"));
    app.use("/scripts", express.static(__dirname + "dist/scripts"));
    app.use("/views", express.static(__dirname + "dist/views"));
    app.use("/fonts", express.static(__dirname + "dist/fonts"));
    app.use("/templates", express.static(__dirname + "dist/templates"));
    app.use("/images", express.static(__dirname + "dist/images"));


  app.all('/*', function(req, res, next) {
      // Just send the index.html for other files to support HTML5Mode
      res.sendFile('dist/index.html', { root: __dirname });
  });

    var server = app.listen(8080);
    console.log('Node Express server listening on http://%s:%d', server.address().address,8080);
}
else {
    console.log('No /dist folder, did not start the server');
}

Update: Solution 更新:解决方案

Thanks to the comments of the users, I asked the question in a different way and found the solution that make it works here . 多亏了网友的评论,我问的问题以不同的方式,并找到了解决办法,使其工作在这里 That is, the <base href="/"> tag must be located before the <link rel="stylsheet"..> tags (what a hard time I got for such a stupid thing!) 也就是说, <base href="/">标记必须位于<link rel="stylsheet"..>标记之前(对于这样的愚蠢的事情,我很难受!)

Why not use nested routing in angular routing like this ? 为什么不在这样的角度路由中使用嵌套路由?

https://github.com/angular-ui/ui-router https://github.com/angular-ui/ui-router

I wanted this to be just a comment but I can't yet, Have you tried placing the html5 mode below your routes ? 我希望这只是一条评论,但我还没有,您是否尝试过将html5模式放置在路线下方?

Can remove the if statement if you do not need it. 如果不需要,可以删除if语句。

.when('/research/fly', {
        templateUrl: 'views/research-fly.html',
        controller: 'ResearchController'
      })
      .otherwise ({
        templateUrl: 'views/notyetready.html',
      }); 

        if(window.history && window.history.pushState){

         $locationProvider.html5Mode(true);
        }
});

Maybe try using a different pattern to match against that sounds like the cause of the problem 也许尝试使用不同的模式来匹配听起来像是问题的根源

app.all('/**/*', function(req, res, next)

However I would ask why are you serving the static files with node + express? 但是我想问一下,为什么要用node + express服务静态文件? If all you want is a static file server for local development why not try grunt-serve 如果您想要的只是用于本地开发的静态文件服务器,为什么不尝试grunt-serve

Then if you want to serve the static files on a server you can use nginx which works really well with angular in html5 mode 然后,如果您想在服务器上提供静态文件,则可以使用nginx ,它与html5模式下的angular一起使用时效果很好

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM