Nginx conf for prerender + 反向代理到 django + 在 html5 模式下服务 angular

Nginx conf for prerender + reverse proxy to django + serving angular in html5 mode

满嘴的标题说明了一切:

我们有一个 Angular 前端和 Django 后端,提供在端点 example.com/api/v1/*

独立公开的 REST API

Angular 应用程序以 HTML5 模式运行,我们希望 hard-links 到 example.com/foo/bar 将用户带入处于 foo.bar 状态的应用程序如果它是静态页面而不是应用程序状态(其中 foo 不是 api)。

我们 运行 落后于 nginx,我们在 conf 中的基本策略是在 ^~ /scripts/images 等处定义位置以直接提供静态内容,以及^~ /api/* 路由到 django 的位置。在此之下,我们有一个 location ~ ^/.+$ 匹配与上述任何路径不匹配的任何路径和 "sends it to Angular" - 即为我们的索引页面提供服务并将路径附加到基础 url,允许我们的 angular 路由器从那里处理它。

这是我们的完整配置文件:

upstream django {
    server 127.0.0.1:8000 fail_timeout=0;
}

server {
    listen                  80;
    server_name example.com;
    return 301 https://example.com$request_uri;
}

server {
    listen          443;
    server_name example.com;
    client_max_body_size 10M;
    ssl                     on;
    ssl_certificate         /etc/ssl/thawte/example_com.crt;
    ssl_certificate_key     /etc/ssl/thawte/example_com.key;
    ssl_verify_depth 2;
    gzip            on;
    gzip_types      text/plain text/html application/javascript application/json;
    gzip_proxied        any; 

    index index.html;

    location ^~ /index.html {
        gzip_static on;
        root /www/dist;
    }
    location ^~ /images/ {
        expires max;
        root /www/dist;
    }
    location ^~ /scripts/ {
        expires max;
        gzip_static on;
        root /www/dist;
    }

    location ^~ /favicon.ico {
        expires max;
        root /www/dist;
    }

    location ^~ /api {
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Host $http_host;
        proxy_set_header X-Forwarded-Proto https;
        proxy_redirect off;
        proxy_pass http://django;
    }

    //Send anything else to angular 
    location ~ ^/.+$ {
        rewrite .* /index.html last;
    }

}

这对我们来说效果很好,但我们现在需要将其设置为与 prerender.io 一起使用。我们已经尝试了几种方法,对 the official prerender nginx example 进行了修改,但 none 已经奏效 - 爬虫正在获取与用户相同的代码,而不是缓存页面。

我们怎样才能让它工作?

(注意:这对这里涉及的每个人来说都是新领域,因此如果处理此问题的最佳方法涉及退后几步做出不同的选择,请提出建议)

原来上面发布的配置一直在工作。

当我最终想到尝试将 https://example.com/anything 通过爬虫调试器(而不是 https://example.com,这是我之前一直在测试的所有内容)时,我意识到了这一点,并且它起作用了 -爬虫按预期提供了缓存的页面。

这仅仅是因为贪婪量词在:

location ~ ^/.+$ {

不匹配空字符串。还有一个

location = / {
    try_files $uri @prerender;
 }

,我的 conf 按预期工作。

希望我额头上的手印只是 https://example.com 通过爬虫调试器 - 它不起作用。

从好的方面来说,我想下周末我可以把额头上的这个手印变成漂亮的万圣节服装....

仍然不确定我是否以最佳方式解决了这个问题,欢迎提出其他建议。