我将开发一个简单的 Angular 2 应用程序。我使用 Angular CLI 创建了一个带有路由的项目,并使用“ng generate component”命令向应用程序添加了几个组件。然后我在 app-routing.module.ts 中指定了路由,如下所示。
import { NgModule } from '@angular/core'; import { Routes, RouterModule } from '@angular/router'; import { HomeComponent } from './home/home.component'; import { AboutComponent } from './about/about.component'; import { UserComponent } from './user/user.component'; import { ErrorComponent } from './error/error.component'; import { SpecialpageComponent } from './specialpage/specialpage.component'; const routes: Routes = [ { path: '', component: HomeComponent }, { path: 'about', component: AboutComponent }, { path: 'user', component: UserComponent }, { path: 'specialpage', component: SpecialpageComponent }, { path: '**', component: ErrorComponent } ]; @NgModule({ imports: [RouterModule.forRoot(routes)], exports: [RouterModule], providers: [] }) export class AppRoutingModule { }
app.module.ts 如下。
import { BrowserModule } from '@angular/platform-browser'; import { NgModule } from '@angular/core'; import { FormsModule } from '@angular/forms'; import { HttpModule } from '@angular/http'; import { AppRoutingModule } from './app-routing.module'; import { AppComponent } from './app.component'; import { HomeComponent } from './home/home.component'; import { AboutComponent } from './about/about.component'; import { ErrorComponent } from './error/error.component'; import { UserComponent } from './user/user.component'; import { SpecialpageComponent } from './specialpage/specialpage.component'; @NgModule({ declarations: [ AppComponent, HomeComponent, AboutComponent, ErrorComponent, UserComponent, SpecialpageComponent ], imports: [ BrowserModule, FormsModule, HttpModule, AppRoutingModule ], providers: [], bootstrap: [AppComponent] }) export class AppModule { }
我没有为其他组件添加任何修改。然后我使用“ng serve”命令部署了应用程序,该应用程序可以正常使用链接。例如:http://localhost:4200/about
https://i.stack.imgur.com/HaRAb.jpg
但是当我在 http-server 中部署项目时,链接无法按预期工作。我使用“http-server ./dist”命令部署了应用程序,应用程序部署良好,但链接不起作用。当我转到“http://localhost:4200/about”时,出现 404 错误。
https://i.stack.imgur.com/FWOme.jpg
我做错什么了吗?为什么“ng-serve”有效而“http-server”无效?
任何帮助,将不胜感激。提前致谢。
我已将我的项目上传到 github。
imports: [RouterModule.forRoot(routes, {useHash: true})],
。如果它以这种方式工作,您需要在生产服务器上启用 HTML5 pushState。
useHash:true
:D。正如我在最初的评论中所说。您必须配置服务器以支持 HTML5 pushState。 useHash:true
只是为了调试问题的原因。
这个问题通过实施 HashLocationStrategy
解决,它将 #
添加到您的所有路线。您可以通过将 HashLocationStrategy
添加到 AppModule
providers
来实现此目的。
providers: [{provide: LocationStrategy, useClass: HashLocationStrategy}],
并添加相应的导入
import { HashLocationStrategy, LocationStrategy } from '@angular/common';
这将解决您的问题。
如果您不想使用 HashLocationStrategy
,您可以使用 PathLocationStrategy
,这样您的 Angular 应用程序就不会在 URL 中显示 Hash。
这是因为 http-server 不支持像 lite-server 或 web pack-dev server 这样的回退。这就是为什么它显示 404 未找到。有两种解决方案可以解决此问题:
您可以使用上面提到的 HashLocationStrategy 。如果您将其部署到 Apache 或 IIS 服务器,那么您可以简单地添加此处提到的配置!
注意:对于开发,您可以使用 lite-server。
希望这会帮助你。
我已经通过在 AppModule Providers 中添加这个解决了这个问题:
providers: [{provide: LocationStrategy, useClass: PathLocationStrategy}]
并导入
import { PathLocationStrategy, LocationStrategy } from '@angular/common';
然后我创建了.htaccess:
RewriteEngine On
# If an existing asset or directory is requested go to it as it is
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} -f [OR]
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} -d
RewriteRule ^ - [L]
# If the requested resource doesn't exist, use index.html
RewriteRule ^ /index.html
没有 # 在 URL 中,一切都很好 :)
会这样解决:
案例 1:对于低于 Angular 5.1 的版本
1) 使用 HashLocationStrategy 如下所述:在 AppModule 中执行以下操作。
1.1) import { HashLocationStrategy, LocationStrategy } from '@angular/common';
1.2) providers: [{provide: LocationStrategy, useClass: HashLocationStrategy}]
案例 2:对于等于或大于 Angular 5.1 的版本
2.1) Angular 引入了这个属性 onSameUrlNavigation 来克服服务器上的刷新问题。
2.2) 将 onSameUrlNavigation 添加到 imports 数组 中的 RouterModule.forRoot
中。
a) 在应用程序主路由模块,即 app.routing.module.ts / app.routing.ts 添加属性
见下文:
@ngModule({
imports:
[
RouterModule.forRoot(routes, {onSameUrlNavigation: ‘reload’})
],
exports: [RouterModule],
});
希望它可以帮助某人。
它会发生,因为它会找到一个根本不存在的页面,因此是 404。可能的选项:
如果您想使用 http-server,请使用代理,它将所有内容重定向到 http://localhost:your-port。选项:-P 或 --proxy 代理所有无法在本地解析到给定 url 的请求。例如:-P http://someurl.com 根本不要使用 express。使用 express 创建您自己的 http-server 并将所有内容重定向到 index.html 假设 public 是您保存所有转译内容的文件夹。 var express = require('express'); var app = express(); var path = __dirname + '/public';变量端口 = 8080; app.use(express.static(path)); app.get('*', function(req, res) { res.sendFile(path + '/index.html'); }); app.listen(端口);
http-server --port 4200 -P http://someurl.com
在我的情况下引发了一个无限循环
对于 Apache 服务器:
在生产服务器中
在项目根目录中添加或创建“.htaccess”文件,向.htaccess文件添加重写规则,如图
RewriteEngine On
# If an existing asset or directory is requested go to it as it is
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} -f [OR]
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} -d
RewriteRule ^ - [L]
# If the requested resource doesn't exist, use index.html
RewriteRule ^ /index.html
我也遇到了这个问题,找到了一个不需要 HashLocationStrategy 解决方案的解决方案。
问题是,像 tomcat 这样的服务器会查找 Angular 应用程序中不存在的实际文件夹(例如: /about ),因为它是一个单页应用程序。所以每个请求都需要重定向到 index.html。
解决此问题的最简单方法是添加以下 java 类并覆盖 addResourceHandlers() 方法,如下所示:
@Configuration
class WebMVCCustomConfiguration implements WebMvcConfigurer {
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/**").addResourceLocations("classpath:static").resourceChain(true)
.addResolver(new PathResourceResolver() {
@Override
protected Resource getResource(String resourcePath, Resource location) {
String path = "static/";
path += (resourcePath.contains(".") && !resourcePath.equals("index.html")) ? resourcePath : "index.html";
Resource resource = new ClassPathResource(path);
return resource.exists() ? resource : null;
}
});
}
}
这将解决所有问题,并且此解决方案在任何地方都不存在。
您应该尝试从应用程序初始化的点开始指定构建中的 url:
Ng build --prod --base-href="http://your.url.com/subdirectory/etc"
面临此特定问题的确切原因是您的服务器设置。
因此,当您实施应用程序时,您必须采取某些步骤。基本步骤之一是标记路径的特定段,例如:http://domain-name/main 其中 main 是路径段,必须用作服务器设置中的标识符,例如 server.js 或 app.js 用于 IIS 和 Tomcat 部署的节点后端或 webconfig 文件。
标记特定段的原因是,当服务器接收到具有该特定段的任何请求+附加时,您将其重新路由到 www 或公共文件夹中的应用程序,以便角路由器启动。
这个过程称为 url 重写。因此,如果取决于应用程序大小的 Web 服务器或应用程序服务器不受您的控制,那么请使用 hashLocationStratergy 否则使用 pathLocationStartergy 总是很整洁,因为它在历史跟踪和其他美学和性能优势方面很有帮助。
要了解更多信息,您可以访问以下链接:
对于 IIS:https://blog.angularindepth.com/deploy-an-angular-application-to-iis-60a0897742e7
根据 https://angular.io/guide/deployment 中的文档(Apache,您也可以查找 nginx)您需要使用 .htaccess 文件将服务器指向 index.html
RewriteEngine On
# If an existing asset or directory is requested go to it as it is
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} -f [OR]
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} -d
RewriteRule ^ - [L]
# If the requested resource doesn't exist, use index.html
RewriteRule ^ /index.html
对于 Apache 服务器
创建文件名 .htaccess
编辑该文件并编写 index.html 而不是 index.php
对于那些没有任何代码的人,可以在您的 .htaccess 文件中编写以下代码: RewriteEngine On # 如果请求现有资产或目录,请转到它,因为它是 RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} -f [OR] RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} -d RewriteRule ^ - [L] # 如果请求的资源不存在,使用 index.html RewriteRule ^ /index.html
此代码可能不适用于 SSL 证书 - 请联系您的托管服务提供商或访问 https://httpd.apache.org/docs/current/howto/htaccess.html 以参考文档。
在基本 href 字符串中添加一个点。
正确的
<base href="./home">
错误的
<base href="/home">
如果您使用href,请将它们更改为routerlink。
export const routes: Routes =[
**{ path: '', redirectTo: '/', pathMatch: 'full'},**
{ path: 'about', component: AboutComponent},
{ path: 'user', component: UserComponent},
{ path: 'specialpage', component: SpecialpageComponent},
{ path: '**', component: ErrorComponent}
];
查看blockquote的内容。然后在 app.module.ts 中的 providers:[]
处给出“HttpModule”的名称
谢谢。
您可以在注册 RouterModule.forRoot 时执行此操作,您可以使用属性 {useHash: true} 传递第二个对象,如下所示:
import {NgModule} from '@angular/core';
import {BrowserModule} from '@angular/platform-browser';
import {AppComponent} from './app.component';
import {appRoutes} from './app.routes';
@NgModule({
declarations: [AppComponent],
imports: [BrowserModule],
RouterModule.forRoot(appRoutes , {useHash: true})],
providers: [],
bootstrap: [AppComponent],
})
export class AppModule {}
更改您的 index.html
<base href="/">
to
<base href="./">
因为我们使用的是 Tomcat 我们已经提到了 this(.) 用于路由是基于 this(/) 所以和 http-server 一样
我的意思是正常运行 ng serve 你只见过 http://localhost:4200/
但是在服务器上运行你已经把你的构建放入(dist)的 webapps
所以它就像
http://localhost:8080/dist/
所以你需要添加 <base href="./">
我认为这是你的问题可能会得到解决。
在项目文件夹中创建 .htaccess 文件,然后写入
RewriteEngine On
RewriteCond %{HTTP_HOST} ^example\.com$ [NC]
RewriteRule ^ http://www.%{HTTP_HOST}%{REQUEST_URI} [L,R=301,NE]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^ index.html [L]
点击此链接:https://angular.io/guide/deployment
我使用了精简服务器。
npm i -D lite-server
然后在我的 package.json 文件中:
"scripts": {
"ci:serve:employee-onboarding": "ng build --prod --project=employee-onboarding && lite-server -c lite-server-config.json"
}
运行它:npm run ci:serve:employee-onboarding
我的 lite-server-config.json 文件看起来像这样
{
"port": 4201,
"server": { "baseDir": "dist/apps/employee-onboarding" }
}
不定期副业成功案例分享
Hashtag
,我更新了我的答案