【问题标题】:Generate static SEO pages for AngularJS + Spring MVC website为 AngularJS + Spring MVC 网站生成静态 SEO 页面
【发布时间】:2016-10-23 20:31:05
【问题描述】:

我有一个使用 Spring MVC + AngularJS 的项目。所有数据都是动态的。 在这个应用程序中有一些大型的位置数据库。

出于 SEO 目的,需要为每个位置生成一个静态页面并将它们放在 SEO 友好的 URL 上(例如 /localhost/path1/path2/here-is-very-friendly-name )

最好的制作方法是什么?

我应该单独生成一个页面并将它们放在与主应用程序不同的文件夹中(如果是,那么最好的方法是什么?),或者我可以使用 Spring/Angular 来实现它?

(更多信息) 每个位置的对象包含idnamelatitudelongtitudeaddressdistrictcitycountry

【问题讨论】:

  • 你应该在这个问题上悬赏。这很有趣。

标签: javascript java angularjs seo


【解决方案1】:

实际上,这是我的 Angular/SEO 经验。
你必须做出很多改变!


1) 从网址中删除#

app.config(['$locationProvider', function ($locationProvider) {

    $locationProvider.html5Mode({
        enabled: true,
        requireBase: false
    });

}]);

2) 检查您的 MVC 路由

到目前为止,您可能只有一个 HomeController 用于返回 index.cshtml 并启动您的 Angular 应用程序。
从 Angular 路由中删除 # 后,您必须为所有路由设置 MapRoute
因为在这种情况下,您第一次尝试访问诸如www.site.com/any_route Angular App 之类的路由尚未加载,因此它会尝试从 MVC 路由获取页面。但在那之后$routeProvider 尽职尽责。


3) 将 MVC 变量用于元标记

为了更好地索引并与爬虫和机器人成为朋友,我们必须使用 MVC 变量来初始化网站元标记。
如果您通过 Angular 绑定设置页面标题,例如 <title>{{title}}</title>,每当您想通过社交网络分享您的页面时,您将看到 {{title}},因为社交网络无法呈现网站。

<title>@ViewBag.title</title>
<meta name="Description" content="@ViewBag.description">
<meta name="Keywords" content="@ViewBag.keywords">
<meta property="og:title" content="@ViewBag.title" />
<meta property="og:description" content="@ViewBag.description" />

4) 替换元标记的 Angular 绑定

我们的应用是 SPA,所以在加载 Angular 之后,我们就离开了 MVC 游乐场。 我们必须用 MVC 变量替换 Angular 变量。

angular.element('title').remove();
angular.element('meta[name="Description"]').remove();
angular.element('meta[name="Keywords"]').remove();
angular.element('meta[property="og:title"]').remove();
angular.element('meta[property="og:description"]').remove();

var description = angular.element('<meta name="Description" content="{{meta.description}}">');
angular.element('head').prepend(description);    

var keyword = angular.element('<meta name="Keywords" content="{{meta.keywords}}">');
angular.element('head').prepend(keyword);    

var titleOg = angular.element('<meta property="og:title" content="{{meta.title}}" />');
angular.element('head').prepend(titleOg);    

var descriptionOg = angular.element('<meta property="og:description" content="{{meta.description}}" />');
angular.element('head').prepend(descriptionOg);

var title = angular.element('<title ng-bind="meta.title"></title>');
angular.element('head').prepend(title);  

$rootScope.$applyAsync(function () {
    $compile(title)($rootScope);
    $compile(description)($rootScope);
    $compile(keyword)($rootScope);
    $compile(titleOg)($rootScope);
    $compile(descriptionOg)($rootScope);
});

5) 将JSON-lD 用于动态内容

如果您熟悉SCHEMA.org,则最好使用JSON-LD 而不是其他人,因为搜索引擎机器人可以捕获和分析页面加载后动态插入的&lt;script type="application/ld+json"&gt;&lt;/script&gt;s。
您必须检查 Schema Dictionary 才能找到最接近您的数据结构的类型。
比如我公司的json-ld:

<script type="application/ld+json">
    {
        "@context" : "http://schema.org",
        "@type" : "Organization",
        "name" : "داده کاوان امیرکبیر",
        "alternateName" : "ADM | Amirkabir Data Miners",
        "description": "شرکت داده کاوان امیرکبیر | تولید کننده نرم افزارهای تحت وب، از قبیل حسابداری آنلاین 'کاج سیستم' ، سیستم مدیریت پروژه 'تسک من' و ...",
        "url" : "https://adm-co.net",
        "email": "info@adm-co.net",
        "logo": {
            "@type": "ImageObject",
            "url": "http://khoonamon.com/images/ADM_Logo.png",
            "caption": "لوگو داده کاوان امیرکبیر",
            "width": "2480px",
            "height": "1459px"
        },
        "telephone": "+98-21-44002963",
        "address": "تهران، خیابان آیت ا... کاشانی، نبش خیابان عقیل، پلاک 380، طبقه دوم",
        "contactPoint" : [{
            "@type" : "ContactPoint",
            "telephone" : "+98-21-44002963",
            "contactType" : "customer service",
            "contactOption" : "TollFree",
            "areaServed" : "IR",
            "availableLanguage" : "Persian"
        }],
        "sameAs" : [
            "https://google.com/+ADMcoNet-GPlus",
            "https://www.linkedin.com/company/adm-amirkabir-data-miners-?trk=biz-companies-cym",
            "https://instagram.com/AmirkabirDataMiners/",
            "https://www.facebook.com/AmirkabirDataMiners",
            "http://www.pinterest.com/AmirkabirDM/",
            "https://twitter.com/AmirkabirDM",
            "https://www.youtube.com/channel/UCQxP0vZA05Pl9GlyXXQt14A/about"
        ]
    }
</script>

【讨论】:

  • 您好,感谢您的回复。它对于此类应用程序的 SEO 非常有用且信息丰富。但是,这不是原始问题的答案。
  • @user1935987你确定吗??
【解决方案2】:

您是否尝试过 SEO.js (http://getseojs.com/) 和 prerender.io (https://prerender.io/) 等工具。你试过了吗?

【讨论】:

  • 是的,我知道该工具,但这只是页面存在本身的一种解决方法,它根本不回答问题。
【解决方案3】:

我自己没有尝试过,但PhantomJs 可能是能够做到这一点的最佳选择。

您需要一个包含要渲染的端点及其对应的静态文件路径名称的字典。然后,您将遍历每个端点,使用 PhantomJS 呈现给定路径,然后将输出保存到静态文件中。

根据我从您的问题中收集到的信息,您实际上还没有在您的 Angular 应用程序的前端使用这些路径吗?如果是这种情况,那么我会说另一种选择是仅通过 Spring 将它们实际呈现在服务器端。

这里的问题是 Angular 没有考虑同构(客户端和服务器端渲染)。您希望在尚未构建的服务器端进行任何适当的渲染,最好的选择是使用 Spring 来渲染它。

另一个选项是在 Angular Universal 的帮助下更新到同构的 Angular2。如果 Spring 不用于渲染而仅用作应用程序的 API,则此选项将很好地工作。

【讨论】:

    【解决方案4】:

    我不是在 java 中做的,而是在 C# 中做的,如果你让它在 java 中工作,请通知我:

    我发现了一段关于 phantomJs 的代码,并且:

    正如我们的朋友所说,我们启用了 html5 模式,我们使用 IIS 新的写入引擎重写了 C# 中的所有 url,我为带有特定查询参数的 google 请求保留了一个特定规则(找不到它净并且没有太多时间直到工作)。所以我将它们重定向到这个特定页面,我读取重定向的 url,传递它并在 phantomJS 上运行它,然后等待结果返回(需要了解运行进程并取回它的控制台结果),然后,我们从应用程序中删除了 ng-app 属性,并将原始页面传递给谷歌爬虫(我们有两种重定向代码,只有一种有效,最后直到那时,一种是永久的,另一种是临时的)。你自己的页面看起来很粗鲁,但谷歌只看你的架构和结构,所以一切都可以找到。

    我很久没接触过Java了,所以我无法实现它,我只是在春天恢复了一点知识,所以如果你有任何更新通知我,我将不胜感激。

    【讨论】:

      猜你喜欢
      • 2016-11-03
      • 2014-05-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-12-02
      • 2013-06-11
      • 1970-01-01
      相关资源
      最近更新 更多