为AngularJS + Spring MVC网站生成静态SEO页面

时间:2016-06-22 04:58:14

标签: javascript java angularjs seo

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

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

制作它的最佳方式是什么?

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

(有关其他信息) 每个位置的对象包含namelatitudelongtitudeaddressdistrictcity,{{1 },country

4 个答案:

答案 0 :(得分:8)

实际上它是我的角色/ SEO体验 你必须做出很多改变!!

1)从网址中删除#

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

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

}]);

2)查看您的MVC路由

直到现在,也许你有一个HomeController可以返回index.cshtml并启动你的Angular App。
从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)替换元标记的角度绑定

我们的应用程序是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而不是其他人,因为搜索引擎机器人可以捕获并分析在页面加载后动态插入的<script type="application/ld+json"></script>
您必须检查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>

答案 1 :(得分:1)

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

答案 2 :(得分:1)

我自己没有尝试过,但PhantomJs可能是最好的选择。

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

从我的问题中收集到的内容,你还没有在角度应用程序的前端实际使用这些路径吗?如果是这种情况,那么我要说另一种选择是通过Spring实际渲染它们的服务器端。

这里的问题是角度不是考虑同构(客户端和服务器端渲染)。你想在服务器端完成任何尚未构建的正确渲染,最好的选择是使用Spring来渲染它。

另一个选择是更新到Angular2,它在角度通用的帮助下是同构的。如果Spring不用于渲染并且仅用作应用程序的API,则此选项可以正常运行。

答案 3 :(得分:0)

我在java中没有这样做但是C#,如果你在java中使用它,请通知我:

我找到了关于phantomJs的一段代码,并且:

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

很长一段时间我没有使用Java,所以我无法实现它,我只重新获得关于春天的知识,所以如果你通知我,我会很感激更新