Rails资产管道解决了完全错误的路径(那里的绝对文件路径是什么?)

时间:2013-05-31 23:15:57

标签: ruby-on-rails ruby-on-rails-3 ruby-on-rails-3.2 asset-pipeline assets

在开发模式下使用Rails asset_path帮助程序来包含图像时,我看到Rails将资产解析为包含文件系统上图像的绝对路径的URL(实际上,我很认真)。

让我们从css.erb文件开始:

body {
  background-image: url(<%= asset_path "cork.bg.gif" %>);
}

从帮助程序返回的路径在编译的CSS中看起来很好......

body {
  background: url(/assets/cork.bg.gif);
}

...但是当浏览器请求/assets/cork.bg.gif时,那就是所有地狱都破裂了。以这个例子(真实的截图):

WTF is this?

更重要的是,日志显示中间件实际上正在发出两个请求

Started GET "/assets/cork.bg.gif" for 127.0.0.1 at 2013-05-31 18:52:39 -0400
Served asset /cork.bg.gif - 200 OK (0ms)

Started GET "/var/www/corkboard.me/app/assets/images/cork.bg.gif" for 127.0.0.1 at 2013-05-31 18:52:39 -0400

ActionController::RoutingError (No route matches [GET] "/var/www/corkboard.me/app/assets/images/cork.bg.gif"):
  actionpack (3.2.13) lib/action_dispatch/middleware/debug_exceptions.rb:21:in `call'
  actionpack (3.2.13) lib/action_dispatch/middleware/show_exceptions.rb:56:in `call'
  railties (3.2.13) lib/rails/rack/logger.rb:32:in `call_app'
  railties (3.2.13) lib/rails/rack/logger.rb:16:in `block in call'
  activesupport (3.2.13) lib/active_support/tagged_logging.rb:22:in `tagged'
  railties (3.2.13) lib/rails/rack/logger.rb:16:in `call'
  actionpack (3.2.13) lib/action_dispatch/middleware/request_id.rb:22:in `call'
  rack (1.4.5) lib/rack/methodoverride.rb:21:in `call'
  rack (1.4.5) lib/rack/runtime.rb:17:in `call'
  activesupport (3.2.13) lib/active_support/cache/strategy/local_cache.rb:72:in `call'
  rack (1.4.5) lib/rack/lock.rb:15:in `call'
  actionpack (3.2.13) lib/action_dispatch/middleware/static.rb:63:in `call'
  railties (3.2.13) lib/rails/engine.rb:479:in `call'
  railties (3.2.13) lib/rails/application.rb:223:in `call'
  railties (3.2.13) lib/rails/railtie/configurable.rb:30:in `method_missing'
  unicorn (4.6.2) lib/unicorn/http_server.rb:552:in `process_client'
  unicorn (4.6.2) lib/unicorn/http_server.rb:632:in `worker_loop'
  unicorn (4.6.2) lib/unicorn/http_server.rb:500:in `spawn_missing_workers'
  unicorn (4.6.2) lib/unicorn/http_server.rb:142:in `start'
  unicorn (4.6.2) bin/unicorn_rails:209:in `<top (required)>'
  /usr/bin/unicorn_rails:23:in `load'
  /usr/bin/unicorn_rails:23:in `<main>'


  Rendered /usr/lib/ruby/gems/1.9.1/gems/actionpack-3.2.13/lib/action_dispatch/middleware/templates/rescues/routing_error.erb within rescues/layout (0.7ms)

我不明白发生了什么,解决问题非常令人沮丧。这是浏览器的一个请求。什么可以添加绝对文件路径?

这是我的application.rb和development.rb配置文件。请帮忙。谁给了我解决这个问题的答案,可以免费注册一年的NoteApp(https://noteapp.com

application.rb中

require File.expand_path('../boot', __FILE__)

require 'rails/all'

# If you have a Gemfile, require the gems listed there, including any gems
# you've limited to :test, :development, or :production.
Bundler.require(:default, Rails.env) if defined?(Bundler)

SITE_CONFIG = YAML.load_file("config/config.yml")[Rails.env]

module Corkboard
  class Application < Rails::Application
    # Settings in config/environments/* take precedence over those specified here.
    # Application configuration should go into files in config/initializers
    # -- all .rb files in that directory are automatically loaded.

    # Custom directories with classes and modules you want to be autoloadable.
    # config.autoload_paths += %W(#{config.root}/extras)

    # Only load the plugins named here, in the order given (default is alphabetical).
    # :all can be used as a placeholder for all plugins not explicitly named.
    # config.plugins = [ :exception_notification, :ssl_requirement, :all ]

    # Activate observers that should always be running.
    # config.active_record.observers = :cacher, :garbage_collector, :forum_observer

    # Set Time.zone default to the specified zone and make Active Record auto-convert to this zone.
    # Run "rake -D time" for a list of tasks for finding time zone names. Default is UTC.
    # config.time_zone = 'Central Time (US & Canada)'

    # The default locale is :en and all translations from config/locales/*.rb,yml are auto loaded.
    # config.i18n.load_path += Dir[Rails.root.join('my', 'locales', '*.{rb,yml}').to_s]
    # config.i18n.default_locale = :de

    # JavaScript files you want as :defaults (application.js is always included).
    # config.action_view.javascript_expansions[:defaults] = %w(jquery rails)

    # Configure the default encoding used in templates for Ruby 1.9.
    config.encoding = "utf-8"

    # Configure sensitive parameters which will be filtered from the log file.
    config.filter_parameters += [:password, :xdr_data]

    config.assets.enabled = true
    config.assets.version = '1.1'
  end
end

development.rb

Corkboard::Application.configure do
  # Settings specified here will take precedence over those in config/application.rb

  # In the development environment your application's code is reloaded on
  # every request.  This slows down response time but is perfect for development
  # since you don't have to restart the webserver when you make code changes.
  config.cache_classes = false

  # Log error messages when you accidentally call methods on nil.
  config.whiny_nils = true

  # Show full error reports and disable caching
  config.consider_all_requests_local       = true
  config.action_controller.perform_caching = false

  # Don't care if the mailer can't send
  config.action_mailer.raise_delivery_errors = false

  # Print deprecation notices to the Rails logger
  config.active_support.deprecation = :log

  # Only use best-standards-support built into browsers
  config.action_dispatch.best_standards_support = :builtin

  # Set header for nginx to handle large uploads.
  # e.g. http://thedataasylum.com/articles/how-rails-nginx-x-accel-redirect-work-together.html
  config.action_dispatch.x_sendfile_header = 'X-Accel-Redirect'

  config.assets.compress = false
  config.assets.debug = true
  config.assets.digest = false

  config.serve_static_assets = true
end

修改:添加了nginx配置。

worker_processes 1;
user nobody nogroup;

pid /tmp/nginx.pid;
error_log /var/www/corkboard.me/log/nginx.error.log;

events {
  worker_connections 1024; # increase if you have lots of clients
  # Set this to on if you have more than 1 working processes
  # This will allow only one child to watch the pollset and accept
  # a connection to a socket
  accept_mutex off; # "on" if nginx worker_processes > 1
}

http {
  include mime.types;
  default_type application/octet-stream;
  access_log /var/www/corkboard.me/log/nginx.access.log combined;

  # This tells Nginx to ignore the contents of a file it is sending
  # and uses the kernel sendfile instead
  sendfile on;

  # Set this to on if you have sendfile on
  # It will prepend the HTTP response headers before
  # calling sendfile()
  tcp_nopush on;

  # This disables the "Nagle buffering algorithm" (Nginx Docs)
  # Good for websites that send a lot of small requests that
  # don't need a response
  tcp_nodelay off;

  gzip on;
  gzip_http_version 1.0;
  gzip_proxied any;
  gzip_min_length 500;
  gzip_disable "MSIE [1-6]\.";
  gzip_types text/plain text/html text/xml text/css
             text/comma-separated-values
             text/javascript application/x-javascript
             application/atom+xml;

  upstream unicorn_server {
    # This is the socket we configured in unicorn.rb
    server unix:/var/www/corkboard.me/tmp/sockets/unicorn.sock
    fail_timeout=0;
  }

  server {
    listen 80;
    listen 443 ssl;
    ssl_certificate      /path/to/file.crt;
    ssl_certificate_key  /path/to/file.key;

    server_name hello.corkboard.me;

    location / {
      proxy_pass http://127.0.0.1:8000;
      proxy_set_header Host $host;
    }
  }

  server {
    listen 80;
    listen 443 ssl;
    ssl_certificate      /path/to/file.crt;
    ssl_certificate_key  /path/to/file.key; 

    client_max_body_size 4G;
    server_name .corkboard.me;

    keepalive_timeout 5;

    rewrite ^ https://noteapp.com$request_uri? permanent;
  }

  server {
    listen 80;
    listen 443 ssl;
    server_name www.noteapp.com;

    ssl_certificate      /path/to/file.crt;
    ssl_certificate_key  /path/to/file.key;

    keepalive_timeout 5;

    rewrite ^ https://noteapp.com$request_uri? permanent;
  }
  server {
    listen 80;
    listen 443 default_server ssl;
    ssl_certificate      /path/to/file.crt;
    ssl_certificate_key  /path/to/file.key;

    client_max_body_size 4G;
    server_name noteapp.com;

    keepalive_timeout 5;

    # Location of our static files
    root /var/www/corkboard.me/public;

    location / {
      set $https_val "";

      if ($server_port = 443) {
        set $https_val "https";
      }

      proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
      proxy_set_header X-FORWARDED_PROTO $https_val;
      proxy_set_header Host $http_host;
      proxy_redirect off;

      # If you don't find the filename in the static files
      # Then request it from the unicorn server
      if (!-f $request_filename) {
        proxy_pass http://unicorn_server;
        break;
      }
    }

    error_page 502 503 /maintenance.html;
    error_page 500 504 /500.html;
  }
}

1 个答案:

答案 0 :(得分:1)

好吧,看起来我应该更彻底地阅读资产管道文档。我错过了与X-Sendfile标题相关的大红框:

http://guides.rubyonrails.org/asset_pipeline.html#x-sendfile-headers

我道歉。由于复制/粘贴作业不正确,标题不包含在上面的nginx配置中。