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

时间:2012-06-29 12:29:56

标签: ruby-on-rails fonts font-face asset-pipeline font-awesome

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

enter image description here

  • Chrome在开发和制作中渲染图标
  • 这只会影响FireFox(虽然我没有尝试IE)
  • 应用程序是here,如果有人能够确认这不仅仅发生在我的计算机上(帮助我排除本地主机缓存问题),我将不胜感激。
  • 所有资产(包括字体和样式表)都使用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;
}

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

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

最后,我将所有4个字体文件放在app/assets/fonts中。

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

7 个答案:

答案 0 :(得分:25)

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

登录AWS - &gt; AWS管理控制台 - &gt; S3 - &gt;找到您的水桶 - &gt;推送属性按钮(由于某种原因在纸上的放大镜) - &gt;右边的Clic PERMISSIONS - &gt; &#34;编辑CORS配置&#34;

<CORSConfiguration>
    <CORSRule>
        <AllowedOrigin>*</AllowedOrigin>
        <AllowedMethod>GET</AllowedMethod>
        <MaxAgeSeconds>3000</MaxAgeSeconds>
        <AllowedHeader>Content-*</AllowedHeader>
        <AllowedHeader>Host</AllowedHeader>
    </CORSRule>
</CORSConfiguration>

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

答案 1 :(得分:13)

我解决了我的问题。

this article,我了解到:

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

     

[即。访问控制允许来源]

而且,来自this article

  

可悲的是,现在S3不允许您指定对象随附的Access-Control-Allow-Origin标头

所以你有几个选择:

  1. 从应用的公用文件夹中提供字体,而不是从S3
  2. 提供
  3. 从Rackspace提供字体,可以设置标题
  4. 将字体嵌入Base64 string
  5. 我已经选择了第一个选项,因为这将是一个流量较低的网站,但这里有一个关于如何serve fonts from Rackspace同时提供来自S3的所有其他资产的好文章。


    <强>更新

    亚马逊announced yesterday他们现在支持跨源资源共享(CORS),因此不再需要上面发布的解决方案。他们的developer guide解释得更多。

答案 2 :(得分: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/

答案 3 :(得分: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

-----

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

答案 4 :(得分:1)

您可以使用以下站点对Base64编码字体。尝试使用FontSquirel,但它不允许您加密版权/购买的字体。

http://base64fonts.com/convert.php

答案 5 :(得分:1)

只需在s3中添加整个存储桶的标题即可。

http://aws.typepad.com/aws/2012/08/amazon-s3-cross-origin-resource-sharing.html

答案 6 :(得分:0)

此线程有更新。似乎无法通过将cors.xml文件上传到存储桶来设置CORS。现在你必须点击它;)。这个线程在寻找解决方案时节省了一些时间,但另一方面我丢失了一些上传和更改cors.xml文件的时间。

目前的解决方案是点击水桶的属性&gt;许可&gt;然后单击“添加CORS配置”