【问题标题】:Accessing images on production, from javascript, in Rails 4在 Rails 4 中从 javascript 访问生产中的图像
【发布时间】:2014-03-14 03:05:37
【问题描述】:

似乎现在在使用资产管道和 sprocket-rails gem 的 Rails 4 中,当处理图像时,它们的文件名会附加一个 md5 指纹,如 css 和 javascript。虽然这是有道理的,因为md5 fingerprints are awesome,它使得从 javascript 访问该图像变得越来越困难。在 rails 3.2 中,我可以使用 /assets/image_name.jpg 访问图像并且它可以正常使用,但是在 rails 4 中该资产不存在,它只存在于名称中的 md5 指纹。

我知道 rails 提供了通过 erb <%= asset-url("image_name.jpg") %> 访问图像的助手,但这在 javascript 中不太理想,因为我没有在我的 js 中使用 erb。有很多方法可以通过视图中提供的数据属性或在我的视图中使用脚本标签并设置一些全局变量来破解此问题,但我正在寻找解决此问题的好方法(如果存在)。

感谢您的帮助。

【问题讨论】:

    标签: ruby-on-rails-4 asset-pipeline sprockets


    【解决方案1】:

    为什么需要对图片使用资产管道?我得到了散列行为。但通常资产会被预处理。如果您像过去一样将图像放在公共层次结构中,您将获得正常的路径路由。

    这是来自Asset Pipleline 指南的引用,我认为这可能是密切相关的。 “资产仍然可以放置在公共层次结构中。公共下的任何资产都将由应用程序或 Web 服务器作为静态文件提供。您应该将应用程序/资产用于在提供之前必须经过一些预处理的文件。”

    【讨论】:

    • 如果我想利用图像资产的指纹来破坏更新缓存怎么办?如何从 javascript 变量中访问指纹图像?
    • 我正在寻找同样的东西,我找到了这个。它可以满足您的需求。 github.com/johnnypez/assets_js.
    【解决方案2】:

    不幸的是,我认为您要么向 JS 添加 ERB 扩展并使用资产帮助程序,要么不使用资产的资产管道。

    【讨论】:

      【解决方案3】:

      当你说“我没有在我的 js 中使用 erb”时,你的意思是你不想,还是只是不想?因为你可以!

      如果您使用扩展名.js.erb 重命名相关的 JS 文件,那么您可以在这些文件中使用 asset_url 帮助程序,如下所示:

      var src = "<%= asset_url('photo.jpg') %>";
      

      【讨论】:

      • 如果您要处理大量图像并动态填充 src(在 JS 中),这不是一个好的选择——而不是像您那样硬编码。
      【解决方案4】:

      另一个要考虑的选项(尽管我不推荐)是在应用程序控制器中使用自定义路由来为您在控制器中获取资产路径,并使用 md5 哈希将 URL 返回到资产,或者可能只需渲染资产的原始二进制数据(尽管这会给您的应用程序增加处理开销)。

      例如,您发出 AJAX 获取请求 http://yourapp.com/images?file=my_image.jpg

      然后在您的控制器中,您的操作方法将如下所示:

      def images
        ActionController::Base.helpers.asset_url(params[:file])
      end
      

      这将返回资产的 url 路径。这种方法的缺点是它需要你在 JS 端发出两个请求。第一个获取资源的路径,第二个使用返回的路径实际加载该资源。

      要将这减少到一个请求,您可以让应用程序从文件系统中读取图像并返回正确的标头,以便浏览器认为它是正在返回的图像,因此将呈现提供的 url。但是,这对于应用程序来说会做更多的工作,并且在您的服务器上会产生更多不需要的磁盘 IO。

      客户端上的每个图像可能需要两次请求才能实现您想要的,但您必须在某个地方做出牺牲...

      【讨论】:

      • 这可以通过使用redirect_to 简单地将浏览器请求重定向到正确的资产来处理“JS 端的一个请求”。虽然从技术上讲它仍然是两个请求,但您不需要再编写任何 JS 代码来处理它。你会这样做:redirect_to ActionController::Base.helpers.asset_url(params[:file]) ...但是绕过资产管道会出现问题(缓存等),因此绝对不建议将其用于实际生产用途。不过,在 prod 中进行一次性和简单的让我看看这件事的测试应该没问题。
      • 是的,@KarlWilbur 是对的,redirect_to 似乎是一个更清洁的解决方案。
      猜你喜欢
      • 2014-04-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-04-10
      • 1970-01-01
      • 2014-10-12
      • 1970-01-01
      相关资源
      最近更新 更多