zoukankan      html  css  js  c++  java
  • 解决Ruby On Rails下使用SwfUpload等Flash上传组件取不到Session

    最近刚做好一个站,rails 3,大家捧场看看,谢谢!www.yo945.com

      

    SwfUpload相当的好用,在让我在写前台功能的时候,是相当的爽快,然后写后台,OK,相当相当的爽快,相当相当的给力,可同时上传N个文件,显示进度,上传完成支持回调,相当好用!可是,当我在给后台加上用户登录验证时,发现居然取不到session了?!无论如何也取不到!相当相当的郁闷了……

      分析了一下,主要原因是因为Rails为了安全,启用了CSRF验证,而SwfUpload因为FLASH对于安全设置的要求,又不允许随意设置HTTP头,而且默认也是不加上cookie的,所以导致上传时没有cookie也没有session_id。

      解决之道,就是要让SwfUpload带上该带的数据,又要让Rails通过验证,具体作法,记录如下。

      首先,如果本次操作是必须要有cookie中带的信息的,那么先要让swfuplod带上cookie信息,这步不是必须的,看个人需要,做起来也是相当的简单,因为在下载下来的SWFUpload v2.2.0.1 Core中,本身就带了一个pluggin,就是plugins\swfupload.cookies.js,引用的时候先引用swfupload组件,再引用swfupload.cookie.js即可,不有再做任何额外操作,在提交时自动就会带上cookie信息。加上这个插件后,swfuplod多了一个方法,就是refreshCookies,功能么一看函数名就知道了。插件的原理很简单,就是读取document.cookie然后给swfupload的post_params设置值而已,所以如果嫌它写得麻烦,自己设置一下也是很简单的。

      第二步,给post_params加上两个必须属性,这是关键一步。第一个参数,就是CSRF的值,第二个参数,就是session_id值。大致上,可以这样写,先通过服务器帮助,设置属性值给一个参数对象,然后在初始化的时候设置给post_params.

    //这是CSRF那一长串字符
    var _token = '<%=form_authenticity_token-%>';
    //这是session_id值
    var _session_id = '<%=cookie[Rails.application.config.session_options[:key]]-%>';
    //这是session的名称,具体设置在config/initializers/session_store.rb里面
    var _session_key = '<%-Rails.application.config.session_options[:key]%>';
    //设置一个参数对象
    var params = {
        'authenticity_token':_token
    }
    params[_session_key] = _session_id
    //如果有别的要提交的参数一一起设置了,然后设置给post_params

      第三步,设置服务器端。

      1.在app下,建立一个middleware文件夹,在里面建立一个中间件的ruby文件,名字随意,我这里叫flash_session_cookie_middleware.rb,事实上网上找来的资料里面都叫这名字,这出自国外一篇文章。代码如下:

    require 'rack/utils'
    
    class FlashSessionCookieMiddleware
      def initialize(app, key='_fly84_session')
        @app = app
        @session_key = key
      end
    
      def call(env)
        if env['HTTP_USER_AGENT'] =~ /^(Adobe|Shockwave) Flash/
          req = Rack::Request.new(env)
          env['HTTP_COOKIE'] = [ @session_key, req.params[@session_key] ].join('=').freeze unless req.params[@session_key].nil?
          #env['HTTP_ACCEPT'] = "#{req.params['_http_accept']}".freeze unless req.params['_http_accept'].nil?
        end
        @app.call(env)
      end
    end

      2.加入配置

    config/application.rb下,加入

    config.autoload_paths += %W( #{Rails.root.to_s}/app/middleware )

    config/initializers/session_store.rb中,加入

    Rails.application.config.middleware.insert_before(Rails.application.config.session_store, FlashSessionCookieMiddleware, Rails.application.config.session_options[:key])

    Rails.application.config.session_options[:key]就是在session_store里面设置的那个session的名字

      好了,就这么多了,设置是挺简单的,原理也很容易理解,就是我自己也不明白,为什么会为了这个弄了N久。第一次弄的时候,连找资料,半小时就好了,然后有点小开心,喝了杯咖啡散了个步,结果再一测试就不行了,然后再找原因再改的,到最后也基本还是这样。但愿接下来顺利。

  • 相关阅读:
    CUBRID学习笔记 44 UPDATE 触发器 更新多表 教程
    解决Tomcat出现内存溢出的问题
    用视图+存储过程解决复杂查询的排序分页问题
    IIS的安装与配置
    UI设计
    2 睡觉
    HTML5的新结构标签
    聚合函数
    Sql Group by 语句
    口语第一课
  • 原文地址:https://www.cnblogs.com/varlxj/p/2089131.html
Copyright © 2011-2022 走看看