当我转到网络应用程序并单击其中一个 routerLink 时,服务器会运行 .js 模块来显示内容。当我刷新该确切页面(预渲染的)时,我收到 301 错误。
url/cases,301,位置:url/cases/
我在 url/cases/ 之后获得了 200 个代码
.htacces
<IfModule Litespeed>
RewriteEngine On
# Redirect www to non-www and HTTP to HTTPS
RewriteCond %{HTTP_HOST} ^www\.(.*)$ [NC]
RewriteRule ^(.*)$ https://%1/$1 [R=301,L]
# Existing rules for handling files and serving index.html
RewriteCond %{REQUEST_FILENAME} -s [OR]
RewriteCond %{REQUEST_FILENAME} -l [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^.*$ - [NC,L]
RewriteRule ^(.*) /index.html [NC,L]
</IfModule>
服务器.ts
import 'zone.js/node';
import { APP_BASE_HREF } from '@angular/common';
import { CommonEngine } from '@angular/ssr';
import * as express from 'express';
import { existsSync } from 'node:fs';
import { join } from 'node:path';
import AppServerModule from './src/main.server';
// The Express app is exported so that it can be used by serverless Functions.
export function app(): express.Express {
const server = express();
const distFolder = join(process.cwd(), '../browser');
const indexHtml = existsSync(join(distFolder, 'index.original.html'))
? join(distFolder, 'index.original.html')
: join(distFolder, 'index.html');
const commonEngine = new CommonEngine();
server.set('view engine', 'html');
server.set('views', distFolder);
// Example Express Rest API endpoints
// server.get('/api/**', (req, res) => { });
// Serve static files from /browser
server.get(
'*.*',
express.static(distFolder, {
maxAge: '1y',
redirect: false
})
);
// All regular routes use the Angular engine
server.get('*', (req, res, next) => {
const { protocol, originalUrl, baseUrl, headers } = req;
const requestedPath = `${distFolder}${originalUrl}`;
// Check if the requested path corresponds to an existing file
if (existsSync(requestedPath)) {
// Serve the file directly without rendering Angular
return res.sendFile(requestedPath);
}
commonEngine
.render({
bootstrap: AppServerModule,
documentFilePath: indexHtml,
url: `${protocol}://${headers.host}${originalUrl}`,
publicPath: distFolder,
providers: [{ provide: APP_BASE_HREF, useValue: baseUrl }],
})
.then((html) => res.send(html))
.catch((err) => next(err));
});
return server;
}
function isRunningOnApachePassenger(): boolean {
return moduleFilename.includes('lsnode.js');
}
function run(): void {
// Start up the Node server
const server = app();
if (isRunningOnApachePassenger()) {
server.listen(() => {
console.log('Node Express listening to Passenger Apache');
});
return;
}
const port = process.env['PORT'] || 4000;
server.listen(port, () => {
console.log(`Node Express server listening on http://localhost:${port}`);
});
}
// Webpack will replace 'require' with '__webpack_require__'
// '__non_webpack_require__' is a proxy to Node 'require'
// The below code is to ensure that the server is run only when not requiring the bundle.
declare const __non_webpack_require__: NodeRequire;
const mainModule = __non_webpack_require__.main;
const moduleFilename = (mainModule && mainModule.filename) || '';
if (
moduleFilename === __filename ||
moduleFilename.includes('iisnode') ||
isRunningOnApachePassenger()
) {
run();
}
export default AppServerModule;
我的路线:
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
const routes: Routes = [
{
path: '',
loadChildren: () =>
import('./pages/home/home.module').then((m) => m.HomeModule),
},
{
path: 'over-ons',
loadChildren: () =>
import('./pages/over-ons/over-ons.module').then((m) => m.OverOnsModule),
},
{
path: 'contact',
loadChildren: () =>
import('./pages/contact/contact.module').then((m) => m.ContactModule),
},
{
path: 'expertises',
loadChildren: () =>
import('./pages/expertises/expertises.module').then((m) => m.ExpertisesModule),
},
{
path: 'expertises/:slug',
loadChildren: () =>
import(
'./pages/expertises/expertise-detail/expertise-detail.module'
).then((m) => m.ExpertiseDetailModule),
},
{
path: 'cases',
loadChildren: () =>
import('./pages/cases/cases.module').then((m) => m.CasesModule),
},
{
path: 'cases/:slug',
loadChildren: () =>
import('./pages/cases/case-detail/case-detail.module').then(
(m) => m.CaseDetailModule
),
},
{
path: 'blogs',
loadChildren: () =>
import('./pages/blogs/blogs.module').then((m) => m.BlogsModule),
},
{
path: 'blogs/:slug',
loadChildren: () =>
import('./pages/blogs/blog-detail/blog-detail.module').then(
(m) => m.BlogDetailModule
),
},
];
@NgModule({
imports: [
RouterModule.forRoot(routes, {
scrollPositionRestoration: 'enabled',
anchorScrolling: 'enabled',
scrollOffset: [0, 150]
}),
],
exports: [RouterModule],
})
export class AppRoutingModule {}
我尝试了一些方法,例如通过添加重定向来更改 server.ts: false 并调整我的路由以在末尾添加 ./ 。我也尝试修改我的 .htaccess 但我无法让它工作。
我正在尝试修复它,以便改进我的 SEO。
我刚刚发现了同样的问题,问题似乎是即使 Angular 最终会路由到(例如)/login,但无论出于何种原因,它都会首先尝试路由到/login/。你能做的最好的事情就是在按钮和“a”标签上将 href 和 routerLink 设置为 /login/ ,这样它就不会得到 301REDIRECT 而是 200OK 。这只是在更改路径并在routes.ts中重定向到各种错误后进行的尝试和错误。
我不知道它如何影响 SEO,我个人认为它不会比 301REDIRECT 更混乱,所以现在我认为这是唯一可能的解决方案。
(站点地图生成器还在网址末尾包含斜杠“/”,所以我认为爬虫不会介意。)
希望有帮助, 快乐编码