Angular网站在尝试直接访问URL时会引发404未找到错误。

huangapple go评论60阅读模式
英文:

Angular website throws 404 not found error when try to access URL directly

问题

我已经构建了Angular网站,一切都在我的本地机器环境上按预期工作。

我已经将网站发布到一个带有Nginx服务器的服务器上,现在每当我在浏览器中访问URL http://example.com/login 时,它会显示404未找到。

我找到了另一种解决方案,我需要在我的URL中添加#,我的URL会显示为 http://example.com/#/login,但我不想在我的URL中显示#

我该如何解决这个问题?

英文:

I have built angular website and everything is working as expected on my local machine environment.

I have published the site on a server with nginx server and now whenever I hit the URL
http://example.com/login in the browser. It gives 404 not found.

I have found the other solution where I have to put # in my URL and my URL shows like
http://example.com/#/login but I do not want to show # in my URL.

How can I fix this problem?

答案1

得分: 2

1. Web服务器路径

基本上,Web服务器是“愚蠢”的,它们提供你告诉它们要查找的文档。如果你导航到 https://www.example.com/,你是在请求Web服务器的根目录。 (在本答案的其余部分,我将使用 / 表示Web服务器的根目录,所以 / = https://www.example.com/)。
如果没有提供默认文档,你要么会得到一个文件列表(如果它很老或已经配置为这样做),要么会得到一个404(未找到)或403(禁止)错误。
默认文档可以是一个列表,例如对于Apache:

DirectoryIndex index.php index.html

这告诉Apache首先查找 index.php,如果没有找到,就查找 index.html,如果你有这两个文件,那么 index.php 的内容会被显示出来(在正确配置的情况下,它会经过PHP预处理器运行)。

1.1 锚点

# 类型的URL之所以有效,是因为 / 会重定向到 /index.html,而 /#<something> 告诉浏览器页面上有一个名称为 <something> 的锚点。Angular将其解释为路由。有关锚点的更多信息,请参见 https://stackoverflow.com/questions/6582233/hash-in-anchor-tags 上的答案。

1.2 Angular路由和路径

当我们定义 Angular 路由,如 /abekat,Angular 并不是要求Web服务器去查找文件 /abekat,而是进行一些JavaScript的“魔术”,显示似乎是不同页面的内容(但实际上是单页应用),然后重写URL以在浏览器中显示路径,而无需请求Web服务器导航到 /abekat
当你复制URL并直接转到 /abekat 时,没有Angular应用程序运行来拦截URL,所以你的浏览器要求Web服务器提供 /abekat 处的文件。

1.2.1 没有错误处理程序时Web服务器的操作

如果错误文档处理程序没有设置为Angular的index.html,Web服务器将要么发送404和路径给任何404处理程序,要么只显示错误。
你还可能碰巧有一个命名匹配(例如使用Apache的MultiViews设置),其中 /abekat 会匹配 /abekat.html,这可能会导致更多混淆。

1.2.2 Angular如何拦截

如果错误文档处理程序设置为Angular的index.html,那么Angular会加载页面,路由模块会读取URL,并尝试将其与配置的路由进行匹配。如果找到匹配的路由,将触发该路由,并显示相应页面。

2. 解决方案

确保Web服务器上的404错误处理程序指向正确的文件。

2.1 Apache

如果你使用Apache HTTP服务器,请将以下内容添加到你的.htaccess文件中:

ErrorDocument 404 /index.html

或者你也可以将其添加到服务器虚拟主机配置中,如果你更喜欢这种方式。

2.2 Nginx

在你的server配置中添加以下内容:

error_page 404 /index.html;
location = /index.html {
    root /path/to/your/html;
    internal;
}

记得重新启动你的Web服务器以重新加载配置。

3. Angular中的404页面

要在Angular中拥有专门的404页面(用于无效的路由),你需要创建一个专门的组件,例如 PageNotFoundComponent,并将 ** 重定向到它,如下所示:

app-routing.module.ts / app.module.ts

const routes: Routes = [
    { path: '', component: DefaultComponent },
    { path: 'create', component: CreateComponent },
    { path: 'edit/:someId', 
        component: EditComponent },
  
    // 用于404请求的通配符路由
    { path: '**', pathMatch: 'full', 
        component: PageNotFoundComponent },
  
];

这应该是你配置中的最后一个路由,以避免它匹配错误的URL。

英文:

1. Paths on webservers

Basically Web servers are "dumb" they serve documents that you tell them to look for. If you navigate to https://www.example.com/ you are asking for the root of the webserver. (for the rest of this answer I will use / to indicate the root of the webserver so / = https://www.example.com/).
If no default document is provided, you either get a list of the files on the webserver (if it is very old, or it has been configured to do so), a 404 (not found) or a 403 (forbidden) error.
The default document can be a list, for example for apache:

DirectoryIndex index.php index.html

This tells Apache to first look for an index.php, and if that is not found, an index.html if you have both files, the contents of index.php are displayed (after being run through the php preprocessor, if configured properly).

1.1 Anchors

The # urls work because / is redirected to your /index.html and /#&lt;something&gt; telling the browser that there is an anchor on the page with &lt;something&gt; as the name. Angular is interpreting that as the route. See answers to https://stackoverflow.com/questions/6582233/hash-in-anchor-tags for more information on anchors

1.2 Angular routing and paths

When we define angular routes like /abekat angular is not asking the webserver to go find the file /abekat but it is doing some javascript "magic" and displaying what seems to be a different page (but it is actually a Single Page Application) and then rewriting the URL to show the path in the browser, which has not been asked to contact the webserver to navigate to /abekat.
When you copy the URL and go to /abekat directly, there is no angular application running to intercept the url, so your bowser asks the webserver to server the file at /abekat.

1.2.1 What the webserver does with no errorhandler

If the errordocument handler is NOT set to an angular index.html, the webserver will either send the 404 and path to whatever 404 handler is present, or just display an error.
You may also by coincidence have a naming match (for example with apache MultiViews set up) where /abekat will match /abekat.html which may result in even more confusion.

1.2.2 How angular intercepts

If the errordocument handler is set to an angular index.html, then the angular loads the page and the routing module reads the url, and tries to match it to the configured routes. If it finds one that matches, that route is triggered, and you get that page displayed.

2. Solution

Make sure that the 404 error handler on your webserver points to the correct file.

2.1 Apache

If you are using apache http server putting

ErrorDocument 404 /index.html

in your .htaccess will solve the issue. You may also add it to the server virtualhost configuration, if you so prefer

2.2 Nginx

inside your server configuration add:

    error_page 404 /index.html;
    location = /index.html {
        root /path/to/your/html;
        internal;
    }

Remember to restart your webserver to reload the configuration.

3. 404 page in angular

To have a dedicated 404 page in angular (for invalid routes) you need to create a dedicated component, for example PageNotFoundComponent and redirect ** to it like this:

app-routing.module.ts / app.module.ts

const routes: Routes = [
    { path: &#39;&#39;, component: DefaultComponent },
    { path: &#39;create&#39;, component: CreateComponent },
    { path: &#39;edit/:someId&#39;, 
        component: EditComponent },
  
    //Wild Card Route for 404 request
    { path: &#39;**&#39;, pathMatch: &#39;full&#39;, 
        component: PageNotFoundComponent },
  
];

This should be the last route in your configuration, to avoid it matching the wrong url.

huangapple
  • 本文由 发表于 2023年4月4日 14:44:32
  • 转载请务必保留本文链接:https://go.coder-hub.com/75926229.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定