无法使用Nginx + Prerender + Meteor设置SSL

时间:2016-05-01 14:11:55

标签: facebook meteor nginx prerender

在使用HTTPS时,我无法配置nginx以返回预呈现的html。

  • nginx,prerender和我的meteor app在同一台服务器上运行。
  • prerender位于端口3033
  • meteor app位于112端口

在meteor中,我已将其配置为指向localhost:3033进行预呈现。

通过以下无SSL 配置,Facebook tool能够成功抓取我的网站:

server {
    listen 80;
    server_name sample.com www.sample.com;

    # strip the "www" subdomain
    if ($host ~* ^www\.(.*)) {
        set $host_without_www $1;
        rewrite ^(.*) http://$host_without_www$1 permanent;
    }

    location / {
        # app is running in port 112 in the same server
        proxy_pass http://127.0.0.1:112;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection 'upgrade';
        proxy_set_header Host $host;
        proxy_cache_bypass $http_upgrade;
    }
}

然而,当我开始使用SSL时,Facebook无法抓取该网站。

server {
    listen 443 ssl;
    server_name sample.com www.sample.com;

    ssl_certificate /etc/letsencrypt/live/sample.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/sample.com/privkey.pem;

    # strip the "www" subdomain
    if ($host ~* ^www\.(.*)) {
        set $host_without_www $1;
        rewrite ^(.*) http://$host_without_www$1 permanent;
    }

    location ~ /.well-known {
        allow all;
    }
    location / {
        # app is running in port 112 in the same server
        proxy_pass http://127.0.0.1:112;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection 'upgrade';
        proxy_set_header Host $host;
        proxy_cache_bypass $http_upgrade;
    }
}
# redirect to https
server {
    listen 80;
    server_name sample.com www.sample.com;
    return 301 https://$host$request_uri;
}

一个观察结果是,每次我使用HTTPS https://sample.com/运行FB工具时,在prerender日志中它会显示http://sample.com不是HTTPS!)。

手动运行curl命令成功

curl http://sample.com:3033/https://sample.com

介于两者之间的地方显然正在将协议https转换为http

2 个答案:

答案 0 :(得分:1)

听起来您正在负载均衡器或类似的东西上终止SSL。在prerender配置中,您只需在将URL发送到预呈现服务器时强制协议为https。

答案 1 :(得分:1)

看来我的nginx配置毕竟很好。

我最终关注了代码here

  1. 我从npm

    添加了 prerender-node

    meteor npm install --save prerender-node

  2. 我创建了 /client/prerender-head.html

    <head><meta name="fragment" content="!"></head>

  3. 我创建了 /server/prerender.js

  4. 请注意我们强制协议为https的部分(类似于@ Prerender.io建议的那样)

    var prerenderio = Npm.require('prerender-node');
    var token;
    var serviceUrl;
    var settings = Meteor.settings.PrerenderIO;
    
    // token
    token = process.env.PRERENDERIO_TOKEN || (settings && settings.token);
    
    // service url (support `prerenderServiceUrl` (for historical reasons) and `serviceUrl`)
    serviceUrl = settings && (settings.prerenderServiceUrl || settings.serviceUrl);
    serviceUrl = process.env.PRERENDERIO_SERVICE_URL || serviceUrl;
    
    if (token) {
      if (serviceUrl) prerenderio.set('prerenderServiceUrl', serviceUrl);
      prerenderio.set('prerenderToken', token);
    
      prerenderio.set('afterRender', function afterRender(error) {
        if (error) {
          console.log('prerenderio error', error); // eslint-disable-line no-console
          return;
        }
      });
    
      prerenderio.set('protocol', 'https');
    
      WebApp.rawConnectHandlers.use(prerenderio);
    }
    
    1. 创建 /settings.json
    2. 将serviceUrl更改为运行prerender实例的位置。

      {
        "PrerenderIO": {
            "serviceUrl": "http://localhost:3033/",
            "token": "yourtoken"
        }
      }
      
      1. 使用meteor --settings settings.json
      2. 运行应用