通过SEO将旧网址重定向到新应用。Angular与 Symfony

前端开发 2026-07-11

我现在遇到一个情况:已有一个网站将被逐步替换成全新版本。但我想继续使用旧的URL,这些URL会存在一段时间,以便在Google的机器人把它们移除之前维持SEO排名。我已经把这些URL映射到了新数据库中的新对象,因此可以通过一个请求API传入旧URL,获取数据来构建要重定向到的目标URL。但我始终无法让它工作,或者说,无法正确返回301代码并重定向到构建好的URL。

我为Node服务器做了一个反向代理,这个服务器与Angular v20一起打包。

这是我的守卫(guard):

import { inject, PLATFORM_ID, RESPONSE_INIT } from '@angular/core';
import { isPlatformServer } from '@angular/common';
import { CanActivateFn, Router } from '@angular/router';
import { map, of, catchError } from 'rxjs';
import { ExamplesService } from '../example/service/examples.service';

export const exampleOldUrlGuard: CanActivateFn = (route) => {
  const router = inject(Router);
  const examplesService = inject(ExamplesService);
  const platformId = inject(PLATFORM_ID);
  const responseInit = inject(RESPONSE_INIT, { optional: true });

  const oldSlug = route.paramMap.get('oldSlug');
  if (!oldSlug) return of(router.createUrlTree(['/list-examples']));

  return examplesService.getExampleByOldUrl({}, oldSlug).pipe(
    map((response) => {
      const data = response?.exampleUrlData;
      const targetPath = data?.url ? ['/example', data.url] : ['/list-examples'];
      const queryParams = data?.exampleDate?.code ? { example_code: data.exampleDate.code } : {};

      const urlTree = router.createUrlTree(targetPath, { queryParams });

      if (isPlatformServer(platformId) && responseInit) {
        responseInit.status = 301;
        responseInit.statusText = 'Moved Permanently';

        responseInit.headers = {
          ...(responseInit.headers || {}),
          Location: router.serializeUrl(urlTree),
        };
      }

      return urlTree;
    }),
    catchError(() => {
      const tree = router.createUrlTree(['/list-examples']);

      if (isPlatformServer(platformId) && responseInit) {
        responseInit.status = 301;
        responseInit.headers = {
          ...(responseInit.headers || {}),
          Location: router.serializeUrl(tree),
        };
      }

      return of(tree);
    })
  );
};

我还把以下内容加入server.ts里的commonEngine配置:

//code    
.then((html) => {
      const location = res.getHeader('Location');

      if (location && (res.statusCode === 301 || res.statusCode === 302)) {
        return res.redirect(res.statusCode, location.toString());
      }

      res.send(html);
    })
    .catch((err) => next(err));
});
//code

问题可能出在哪?这是不是一个可行的方向?这些旧URL不多,大概不超过五千个。

需要说明的是,我不能用我的Symfony API来处理重定向,因为它位于不同的域名上。

解决方案

我最终得出结论,原来的做法是错误的……我把Symfony仅当作一个简单的API来看待,而不是用来生成重定向映射的工具。我为nginx创建了一个从旧URL重定向到新URL的映射,并把它提供给nginx使用。

Old_url_n new_url_n;

当你有映射后,要把它提供给你的vhost,需要把下面的内容添加到你的vhost文件中:

    # Redirections
    location /your_url/ {

        if ($redirect_target) {
            return 301 $redirect_target;
        }

        return 301 /home;
    }

它的作用是:如果请求的URL(例如localhost/details/123,存在于map文件中)存在,它会以301(永久移动)正确重定向到目标地址。如果不存在,就会将用户重定向到your_website/home路径。

然后把下面的配置加入到nginx.conf文件的http块末尾:

        ##
        # Map with redirections from old URLS to new website
        ## 

        map_hash_bucket_size 256;
        map_hash_max_size 65536;

        map $uri $redirect_target {
            default "";
            include /your_path_to_map/redirects.map;
        }
}

map_hash_bucket_size和 map_hash_max_size的取值取决于映射文件的大小及其内容,由你来决定。它的作用是在Nginx内存中创建一个哈希表,随时供Nginx使用。干杯。

站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。

相关文章