【问题标题】:Rails page caching and flash messagesRails 页面缓存和闪存消息
【发布时间】:2011-01-21 13:33:44
【问题描述】:

我很确定我可以对我网站的绝大多数内容进行页面缓存,但阻止我这样做的一件事是我的 Flash 消息不会显示,或者它们会在错误的时间显示。

我正在考虑的一件事是将 Flash 消息写入 cookie,读取它并通过 javascript 显示它,并在消息显示后清除 cookie。 有没有人成功做到这一点或有更好的方法?

谢谢。

【问题讨论】:

    标签: ruby-on-rails caching page-caching


    【解决方案1】:

    可缓存闪存这样做:

    在您的应用程序控制器中:

    after_filter :write_flash_to_cookie
    
    
    def write_flash_to_cookie
        cookie_flash = cookies['flash'] ? JSON.parse(cookies['flash']) : {}
    
        flash.each do |key, value|
            if cookie_flash[key.to_s].blank?
                cookie_flash[key.to_s] = value
            else
                cookie_flash[key.to_s] << "<br/>#{value}"
            end
         end
    
        cookies['flash'] = cookie_flash.to_json
        flash.clear
    end
    

    然后通过 Javascript 读取“flash”cookie 并将消息插入 HTML 中

    【讨论】:

      【解决方案2】:

      我正在处理同样的问题,我发现 cacheable-flash 插件完全符合 KJF 在问题中的描述。

      我认为这比进行过多的 ajax 调用更简单、更好。

      【讨论】:

      • 我认为这是 Rails 的最佳方法。这个问题的大多数其他答案都建议您自己构建,但可缓存闪存 gem 已经解决了这个问题并且很好地解决了这个问题。感谢 Anton 和 Pivotal Labs。
      【解决方案3】:

      一种解决方案是缓存页面,但包含一个 javascript sn-p,它将为您想要动态的部分发出另一个小请求。所以用户将完全下载页面,然后当javascript执行时,它会拉下动态页面元素。

      不久前我写了一篇关于这个的简短博客文章。 http://chase.ratchetsoftware.com/2008/12/rails-caching-dynamic-fragments/

      此外,RailsEnvy 的 Greg Pollack 做了一个截屏视频,他专注于在缓存页面中保存动态数据。 http://railslab.newrelic.com/2009/02/05/episode-5-advanced-page-caching

      希望这会有所帮助,

      追灰

      【讨论】:

      • 我喜欢这个主意。似乎它可能是票。
      • 我认为值得注意的是,这并没有实现页面缓存的全部好处,因为 Rails 进程仍然每次都会被命中,而不是根本不被命中。不过我想不出更好的解决方案。
      • 片段缓存比提供第二个 HTTP 请求更好,后者只请求可以包含在第一个请求中的数据。此策略将使您服务的 HTTP 请求数量增加一倍。
      【解决方案4】:

      您不必缓存整个页面。尝试片段缓存API

      【讨论】:

      • 也许他想缓存整个页面?页面缓存提供了最大的性能提升。
      • 是的,正确的。我现在已经在进行片段缓存以解决闪存问题。
      【解决方案5】:

      老问题...但我通过将 flash 消息包含到我的缓存键中解决了这个问题。

      caches_action :show, cache_path: proc { |c|
        most_recent_update_time = MyClass.order('updated_at DESC').limit(1).first.try(:updated_at).to_i
        { tag: most_recent_update_time.to_s + c.flash.collect{|x| x}.join }
      }
      

      如果您的显示操作中有 Flash 消息,这显然会经常破坏缓存,但如果您不执行大量消息,则效果很好。

      【讨论】:

        【解决方案6】:

        Unobtrusive Flash 将 flash 消息放入 cookie,并通过 JavaScript 显示。它提供了香草和 Bootstrap 风格的 JS 显示逻辑。它适用于普通和 ajax 请求。它也很容易与 AngularJS 等框架挂钩。

        【讨论】:

          【解决方案7】:

          我不使用 Rails,但这是我在 Python 中使用 UUID 的方式:

          # set flash messages like this
          def flash(self, title, body):
            session['flash_messages'].append({
              'title': title,
              'body': body,
              'uuid': uuid().hex  # stores a UUID as a string
            })
          
          ...
          
          self.flash('foo', 'bar')
          

          然后在基本模板中我有这个:

          <script type="text/javascript">
            {% for m in session.flash_messages %}
              if(!Cookies.get('{{m.uuid}}')) {
                Notify('{{m.title}}', '{{m.body}}');
                Cookie.set('{{m.uuid}}', 'true', 86400); // key, value, expiry seconds
              }
            {% endfor %}
          </script>
          

          我会为 Python 挑战者分解它:

          1. 添加 Flash 消息时,您会创建一个唯一 ID 并将其与该消息一起存储。
          2. 在显示消息之前,请检查是否已设置以消息的唯一 ID 命名的 cookie。
          3. 如果尚未设置该 cookie,请闪烁消息并设置 cookie。 cookie 在一天内到期,或者您认为明智的做法。

          现在,如果从缓存中提取此页面,就可以了。在第 2 步,cookie 的测试将通过,因为它已经设置,并且不会显示消息。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2012-01-01
            • 2015-12-26
            • 2012-08-31
            • 1970-01-01
            • 1970-01-01
            • 2012-01-28
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多