【问题标题】:nginx tries to serve .rss/.json itself rather than letting rails/unicorn serve itnginx 尝试自己服务 .rss/.json 而不是让 rails/unicorn 服务它
【发布时间】:2015-09-19 18:02:15
【问题描述】:

我的 rails 应用程序在使用 nginx 和 unicorn 的生产环境中运行得非常好,除了一件事: 请求 /articles.rss/articles.json 会导致 404 错误,在 nginx 日志中显示请求的文件不存在。请求例如/articles?format=rss 有效。所以看起来 .rss 导致 nginx 认为这是一个静态文件而不是动态生成的内容。在开发中(使用 Rails 的内置服务器),这可以正常工作。

我使用h5bp config files for nginx,这是我的站点配置(域名替换):

# www to non-www redirect -- duplicate content is BAD:
# https://github.com/h5bp/html5-boilerplate/blob/5370479476dceae7cc3ea105946536d6bc0ee468/.htaccess#L362
# Choose between www and non-www, listen on the *wrong* one and redirect to
# the right one -- http://wiki.nginx.org/Pitfalls#Server_Name
upstream app {
  server unix:/var/www/rails-cms/shared/tmp/sockets/rails-cms.unicorn.sock fail_timeout=0;
}

server {
  # don't forget to tell on which port this server listens
  listen [::]:80;
  listen 80;

  # listen on the www host
  server_name www.<my domain>;

  # and redirect to the non-www host (declared below)
  return 301 $scheme://<my domain>$request_uri;
}

server {
  # listen [::]:80 accept_filter=httpready; # for FreeBSD
  # listen 80 accept_filter=httpready; # for FreeBSD
  # listen [::]:80 deferred; # for Linux
  # listen 80 deferred; # for Linux
  listen [::]:80;
  listen 80;

  # The host name to respond to
  server_name <my domain>;

  # Path for static files
  root /var/www/rails-cms/current/public;

  try_files $uri/index.html $uri @app;

  location @app {
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto $scheme;
    proxy_set_header Host $http_host;
    proxy_redirect off;
    proxy_pass http://app;
  }

  #Specify a charset
  charset utf-8;

  # Custom 404 page
  error_page 404 /404.html;

  # Include the basic h5bp config set
  include h5bp/basic.conf;
}

【问题讨论】:

    标签: ruby-on-rails nginx unicorn


    【解决方案1】:

    这是因为您包含 h5bp/basic.conf 文件,而该文件又包含 h5bp/location/expires.conf 文件。看看后一个文件的内容:

    # cache.appcache, your document html and data
    location ~* \.(?:manifest|appcache|html?|xml|json)$ {
      expires -1;
      access_log logs/static.log;
    }
    
    # Feed
    location ~* \.(?:rss|atom)$ {
      expires 1h;
      add_header Cache-Control "public";
    }
    

    看到了吗?第一个 location 拦截 .json 请求,第二个 - .rss 请求,因此您的应用永远不会捕获这些请求。

    如果您希望您的应用处理这些请求,您应该完全拒绝h5bp,或者直接注释掉上面提到的locations。

    在这两种情况下,您的应用都应该自己发送缓存标头,当然如果您愿意的话。

    编辑:

    但由于您的jsonrss 内容是动态生成的,我不建议使用缓存标头。

    【讨论】:

    • 感谢您的回答!评论这些部分有效!我之前已经看过它们,但是我认为仅定义缓存行为不会影响 nginx 或 unicorn 是否会为其提供服务。
    • 欢迎您!是的,这就是 Nignx 的工作方式。如果某个location 捕获了请求,那么另一个location 之后就不能这样做(如果它没有在第一个位置内声明,即“嵌套”位置)
    猜你喜欢
    • 1970-01-01
    • 2016-02-09
    • 2018-03-25
    • 2016-05-04
    • 2018-01-06
    • 2015-09-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多