【问题标题】:nginx, prerender and angular routing issuenginx,预渲染和角度路由问题
【发布时间】:2016-04-28 13:48:56
【问题描述】:

我正在开发一个动态的angular 网站(使用html5mode 删除#)。它使用Elasticsearch 来获取一些数据并呈现内容。 nginx 负责映射到Elasticsearch 和我的网站根目录。

为了让整个网站支持 SEO,我正在尝试使用本地实例 (http://localhost:3000) 集成 prerender

我正在拼命尝试结合 nginx location /angular_test 应用预渲染魔法。默认的 nginx 预渲染中间件配置不适用于 locations。在我的 nginx 配置下面找到:

upstream elasticsearch {
    zone elasticsearch 64K;
    server localhost:9200;
}

server {
    listen 80 default_server;
    listen [::]:80 default_server;

    root /var/www/html;

    index index.html index.htm index.nginx-debian.html;

    server_name angular_test_server;

    location /angular_test {
        rewrite_log on;
        error_log /var/log/nginx/localhost.error_log notice;

        set $prerender 0;
        if ($http_user_agent ~* "baiduspider|twitterbot|facebookexternalhit|rogerbot|linkedinbot|embedly|quora link preview|showyoubot|outbrain|pinterest|slackbot|vkShare|W3C_Validator") {
            set $prerender 1;
        }
        if ($args ~ "_escaped_fragment_") {
            set $prerender 1;
        }
        if ($http_user_agent ~ "Prerender") {
            set $prerender 0;
        }
        if ($uri ~ "\.(js|css|xml|less|png|jpg|jpeg|gif|pdf|doc|txt|ico|rss|zip|mp3|rar|exe|wmv|doc|avi|ppt|mpg|mpeg|tif|wav|mov|psd|ai|xls|mp4|m4a|swf|dat|dmg|iso|flv|m4v|torrent|ttf|woff)") {
            set $prerender 0;
        }

        if ($prerender = 1) {
        rewrite .* /$scheme://$host$request_uri?;
        proxy_pass http://localhost:3000;
        break;
        }

        # support html5mode of angular (fallback to index.html and let angular do the routing)
    try_files $uri $uri/ /angular_test/index.html;
    }

    location /es/ {
        rewrite /es/(.*) /$1 break;
        proxy_pass http://elasticsearch;
        proxy_redirect http://elasticsearch /es/;
    }

}

当我访问 http://localhost/angular_test/search?_escaped_fragment_= 时,我得到一个 404,因为 nginx 尝试加载文件 /var/html/www/angular_test/search。这应该由 angulars 路由覆盖(请参阅 try_files 在 index.html 上进行尝试)。 http://localhost/angular_test?_escaped_fragment_= 工作正常

当我使用类似以下的东西时(如https://gist.github.com/thoop/8165802 所建议的那样),它甚至不会进入@prerender 位置部分。

location /angular_test {
    # support html5mode of angular (fallback to index.html and let angular do the routing)
    try_files $uri $uri/ /angular_test/index.html @prerender;
}

有没有办法让这个设置与prerender 一起运行?我有一种感觉,我在这里没有以正确的方式使用 nginx...

【问题讨论】:

    标签: angularjs nginx seo prerender


    【解决方案1】:

    我想出了解决方案。 If is really evil 在 nginx 位置!

    if(...) 逻辑移出location 并移至server 时,它可以工作。这是我的最终配置:

    upstream elasticsearch {
        zone elasticsearch 64K;
        server localhost:9200;
    }
    
    server {
        listen 80 default_server;
        listen [::]:80 default_server;
    
        root /var/www/html;
    
        index index.html index.htm index.nginx-debian.html;
    
        server_name angular_test_server;
    
        set $prerender 0;
        if ($http_user_agent ~* "baiduspider|twitterbot|facebookexternalhit|rogerbot|linkedinbot|embedly|quora link preview|showyoubot|outbrain|pinterest|slackbot|vkShare|W3C_Validator") {
            set $prerender 1;
        }
        if ($args ~ "_escaped_fragment_") {
            set $prerender 1;
        }
        if ($http_user_agent ~ "Prerender") {
            set $prerender 0;
        }
        if ($uri ~ "\.(js|css|xml|less|png|jpg|jpeg|gif|pdf|doc|txt|ico|rss|zip|mp3|rar|exe|wmv|doc|avi|ppt|mpg|mpeg|tif|wav|mov|psd|ai|xls|mp4|m4a|swf|dat|dmg|iso|flv|m4v|torrent|ttf|woff)") {
            set $prerender 0;
        }
    
        location /angular_test {
            rewrite_log on;
            error_log /var/log/nginx/localhost.error_log notice;
    
            #resolve using Google's DNS server to force DNS resolution and prevent caching of IPs
            resolver 8.8.8.8;
    
            if ($prerender = 1) {
                #setting prerender as a variable forces DNS resolution since nginx caches IPs and doesnt play well with load balancing
                #set $prerender "$host:3000";
                rewrite .* /$scheme://$host$request_uri? break;
                proxy_pass http://localhost:3000;
            }
    
            # support html5mode of angular (fallback to index.html and let angular do the routing)
            try_files $uri $uri/ /angular_test/index.html;
        }
    
        location /es/ {
            rewrite /es/(.*) /$1 break;
            proxy_pass http://elasticsearch;
            proxy_redirect http://elasticsearch /es/;
        }
    
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-05-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-11-10
      • 2014-06-22
      • 1970-01-01
      相关资源
      最近更新 更多