Rails 3,@ font-face使用firefox生成失败

ste*_*och 23 fonts ruby-on-rails font-face asset-pipeline font-awesome

我在rails 3应用程序中使用font-awesome,在开发模式下一切正常,但是当我推送到Heroku时,Firefox无法呈现图标,相反,我看到了:

在此输入图像描述

  • Chrome在开发和制作中使图标很好
  • 这只会影响FireFox(虽然我没试过IE)
  • 该应用程序在这里,如果有人能够确认这不仅仅发生在我的机器上(以帮助我排除本地主机缓存问题),我将不胜感激.
  • 所有资产(包括字体和样式表)都使用asset_sync gem 托管在S3上.

这就是我所做的:

将以下内容添加到font-awesome.css.scss的顶部:**

// font-awesome.css.scss
@font-face {
  font-family: 'FontAwesome';
  src: font-url("fontawesome-webfont.eot");
  src: font-url("fontawesome-webfont.eot?#iefix") format("eot"),
       font-url("fontawesome-webfont.woff") format("woff"),
       font-url("fontawesome-webfont.ttf") format("truetype"),
       font-url("fontawesome-webfont.svg#FontAwesome") format("svg");
  font-weight: normal;
  font-style: normal;
}
Run Code Online (Sandbox Code Playgroud)

然后我把它放在application.rb中:

# application.rb
config.assets.paths << Rails.root.join("app", "assets", "fonts")
config.assets.precompile += %w( .svg .eot .woff .ttf )
Run Code Online (Sandbox Code Playgroud)

最后我将所有4个字体文件放入app/assets/fonts.

我真的很想知道我在这里做错了什么.

nde*_*eau 25

这是我在AWS管理控制台中添加到我的存储桶中的配置,用于配置此交叉事物:

登录AWS - > AWS管理控制台 - > S3 - >查找存储桶 - >推送属性按钮(出于某种原因在纸上放大镜) - >右侧的Clic PERMISSIONS - >"编辑CORS配置"

<CORSConfiguration>
    <CORSRule>
        <AllowedOrigin>*</AllowedOrigin>
        <AllowedMethod>GET</AllowedMethod>
        <MaxAgeSeconds>3000</MaxAgeSeconds>
        <AllowedHeader>Content-*</AllowedHeader>
        <AllowedHeader>Host</AllowedHeader>
    </CORSRule>
</CORSConfiguration>
Run Code Online (Sandbox Code Playgroud)

经过两个小时的研究...... :-(

  • 如果它让你感觉更好,我已经浪费了三天时间.谢谢! (3认同)
  • 如果它让你感觉更好,你就救了我两个小时.谢谢! (2认同)

ste*_*och 13

我解决了我的问题.

这篇文章中我了解到:

Firefox拒绝所有跨站点字体请求,除非设置了一些特定的标头:

[即Access-Control-Allow-Origin]

并且,从这篇文章:

遗憾的是,现在S3不允许您指定对象获取的Access-Control-Allow-Origin标头

所以你有几个选择:

  1. 从应用程序的公用文件夹中提供字体,而不是从S3提供
  2. 从Rackspace提供字体,您可以在其中设置标题
  3. 将字体嵌入您的Base64字符串中

我已经选择了第一个选项,因为这将是一个低流量网站,但这里有一个关于如何从Rackspace提供字体同时为S3提供所有其他资产的好文章.


更新:

亚马逊昨天宣布他们现在支持跨域资源共享(CORS),因此不再需要上面发布的解决方案.他们的开发者指南解释更多


Chr*_*ris 6

Amazon S3现在支持CORS,你不再被迫在你的css中嵌入BASE64字体(它会为你节省一些带宽:)

http://aws.amazon.com/about-aws/whats-new/2012/08/31/amazon-s3-announces-cross-origin-resource-sharing-CORS-support/


Tho*_*emm 5

您还可以使用某些机架中间件直接为字体提供所需的访问控制标头到云端.

# config/environment/production.rb

  # Rack Headers
  # Set HTTP Headers on static assets

  config.assets.header_rules = {
    :global => {'Cache-Control' => 'public, max-age=31536000'},
    :fonts  => {'Access-Control-Allow-Origin' => '*'}
  }
  require 'rack_headers'
  config.middleware.insert_before '::ActionDispatch::Static', '::Rack::Headers'

-----

# lib/rack_headers.rb

require 'rack/utils'

module Rack
  class Headers

    def initialize(app, options={})
      @app = app

      default_path = Rails.application.config.assets.prefix || '/assets'
      @asset_path = options.fetch(:path, default_path)

      default_rules = Rails.application.config.assets.header_rules || {}
      @rules = options.fetch(:header_rules, default_rules)
    end

    def call(env)
      dup._call(env)
    end

    def _call(env)
      status, @headers, response = @app.call(env)
      @path = ::Rack::Utils.unescape(env['PATH_INFO'])

      if @path.start_with?(@asset_path)
        set_headers
      end

      [status, @headers, response]
    end

    def set_headers
      @rules.each do |rule, headers|
        case rule
        when :global # Global
          set_header(headers)
        when :fonts  # Fonts Shortcut
          set_header(headers) if @path.match %r{\.(?:ttf|otf|eot|woff|svg)\z}
        when Array   # Extension/Extensions
          extensions = rule.join('|')
          set_header(result) if @path.match %r{\.(#{extensions})\z}
        when String  # Folder
          set_header(result) if
            (@path.start_with? rule || @path.start_with?('/' + rule))
        when Regexp  # Flexible Regexp
          set_header(result) if @path.match rule
        else
        end
      end
    end

    def set_header(headers)
      headers.each { |field, content| @headers[field] = content }
    end
  end
end

-----
Run Code Online (Sandbox Code Playgroud)

此解决方案使用规则根据规则在每个文件上设置不同的标头.这里描述了规则:https://github.com/thomasklemm/butler#providing-rules-for-setting-http-headers.基本上你可以使用Regexp做任何事情,但有文件结尾,文件夹,Web字体和全局标题的快捷方式.