简体   繁体   English

AngularJs路由重载在nodeJs中失败

[英]AngularJs route reaload fails in nodeJs

I managed to get an example app working following several examples, but theres a problem i cant seem to solve. 我设法得到一个遵循几个示例的示例应用程序,但是我似乎无法解决一个问题。 In the angular app routes work ok like this: - http://localhost:8888/#/login works 在有角度的应用程序路由中,可以像这样正常工作: - http://localhost:8888/#/login工作

but when i reload the url i get the Cannot GET /login error from nodeJs. 但是当我重新加载网址时,我从nodeJs收到Cannot GET / login错误。

i tried doing this: 我尝试这样做:

app.get('/*', function (req, response) {
    response.write(__dirname + '/../Client/index.html');
    response.end();
});

and this 和这个

  app.get('/login', function (req, response) {
    console.log('*****************************************');
    response.sendfile(path.resolve(__dirname + '/../Client/'));
});

but none work, i always get the same error and in the first one it just writes the url. 但没有任何工作,我总是会遇到相同的错误,并且在第一个错误中,它只会写入网址。

I think the problem is that while in the app angular knows the routing and handle the reloads because the file is served with 我认为问题在于,在应用程序中,Angular知道路由并处理重新加载,因为文件与

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

but when the url doesnt have the angular hashtag nodejs tries to look for the url but fails. 但是当URL没有角度标签时,nodejs会尝试查找URL,但会失败。 is there a way i fix this? 有办法解决这个问题吗? maybe redirecting to the correct url or something, i searched for hours trying stuff but none worked, thanks for taking your time. 也许重定向到正确的URL或其他内容,我搜索了数小时来尝试一些东西,但没有任何效果,感谢您抽出宝贵的时间。

The error is generated from the fact that Angular will rewrite the window.location at runtime while you are using your application starting from the root localhost/ and routing you to localhost/login (without calling the server with a GET). 该错误是由于以下事实而产生的:当您从根localhost/开始使用您的应用程序并将您路由到localhost/login (而不用GET调用服务器)时,Angular会在运行时重写window.location。 So, when you refresh, the browser didn't know that the url was written by javascript, so he calls the node server that reject the request. 因此,刷新时,浏览器不知道该URL是由javascript编写的,因此他调用拒绝该请求的节点服务器。 I other word: you need to start your navigation always from the root.. but this is unusable. 换句话说:您需要始终从根目录开始导航。但这是不可用的。

So I figure out how to develop a single project with Angular (4 in my case) for the front-end and nodejs-express for the back-and. 因此,我想出了如何使用Angular(在我的情况下为4)开发单个项目的前端,然后使用nodejs-express进行开发。

I've tested this solution for redirect with fragment from different source like auth0 and the use of JSON Web Token. 我已经测试了此解决方案的重定向,该重定向使用了来自不同来源(如auth0)的片段和JSON Web令牌的重定向。

This let me to deploy this application easily to a single heroku instance. 这使我可以轻松地将此应用程序部署到单个heroku实例。

NodeJs Configuration NodeJs配置

The first middlewere have to be the path where the Angular's app is build 首先必须是Angular应用程序的构建路径

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

Then I have configured express-jwt (the regular expression is for all the url that not starts with "/api") 然后,我配置了express-jwt (正则表达式用于所有不以“ / api”开头的url)

app.use(expressJwt({secret: appConfig.SecurityJwt}).unless({
  path: [
    '/api/v1/login',
    /^(?!\/api).*/gm
  ]
}));

Then the business logic of front end: 然后是前端的业务逻辑:

app.post('/api/v1/login', ...
app.get('/api/v1/myOtherServices' ....

And in the very end of routing configuration, even after the custom error handler: 在路由配置的最后,甚至在自定义错误处理程序之后:

app.use(appHandleError);


app.get('*', function (req, res) {
  res.sendFile('index.html', {root: './dist'});
});

app.listen(4200);

Angular routing 角路由

I did not do anything particular here: 我在这里没有做任何特别的事情:

const routes: Routes = [
  {path: 'home', component: LoginComponent},
  {path: 'authenticated', component: ActivatePageComponent},
  {path: '', redirectTo: '/home', pathMatch: 'full'}
];

@NgModule({
  imports: [RouterModule.forRoot(routes, {useHash: false, enableTracing: false})],
  exports: [RouterModule]
})
export class AppRoutingModule {
}

Then in the package.json I have made a custom script: 然后在package.json中,我做了一个自定义脚本:

  "scripts": {
    "ng": "ng",
    "start": "node server.js",
    "build": "ng b --prod",
    "test": "ng test",
    "lint": "ng lint",
    "e2e": "ng e2e",
    "postinstall": "ng b --prod",
    "buildAndStart": "ng build && npm start",
    "i18n": "ng-xi18n --i18nFormat=xlf"
  },

That I can launch with the command npm run buildAndStart so the angular project is builded and the server node is up and running. 我可以使用命令npm run buildAndStart来启动它,以便npm run buildAndStart角度项目并启动并运行服务器节点。

My angular app will be listening to http://localhost:4200/ and all the rest service at the /api/* path as well. 我的角度应用程序将在/api/*路径中监听http://localhost:4200/和所有其他服务。

So, for example, url like: 因此,例如,URL:

http://localhost:4200/authenticated#access_token=123
http://localhost:4200/authenticated?access_token=123

will be evaluated by Angular, and Angular can call all the /api/v1/myOtherServices without any problem, even the refresh/reload will not generate any error this time. 将由Angular进行评估,并且Angular可以/api/v1/myOtherServices调用所有/api/v1/myOtherServices ,即使刷新/重新加载这次也不会产生任何错误。

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

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