1 如何使用Cookies
  从controller中调用直接调用cookies方法就能得到cookies,
  读取的cookies是从request中读取的时候读取的,
  读取的时候不会把cookie对象取回来,只会把它包含的值取回来
    写入的cookies将会和response一起发送出去,
  1.   # Examples for writing:
  2.   #
  3.   #   # Sets a simple session cookie.
  4.      cookies[:user_name] = "david"
  5.   #
  6.   #   # Sets a cookie that expires in 1 hour.
  7.      cookies[:login] = { :value => "XJ-122":expires => 1.hour.from_now }
  8.   #
  9.   # Examples for reading:
  10.   #
  11.      cookies[:user_name# => "david"
  12.      cookies.size        # => 2
  13.   #
  14.   # Example for deleting:
  15.   #
  16.      cookies.delete :user_name
支持的symbol包括::value, :path, :domain, :expires, :secure, :http_only

2 实现
  1.   module Cookies
  2.     def self.included(base)
  3.       base.helper_method :cookies
  4.     end
  5.     protected
  6.       # Returns the cookie container, which operates as described above.
  7.       def cookies
  8.         CookieJar.new(self)
  9.       end
  10.   end
可以看到提供了一个cookies方法,并通过helper_method开放给view访问
下面主要看CookieJar的实现:
  1.   class CookieJar < Hash #:nodoc:
  2.     def initialize(controller)
  3.       @controller@cookies = controller, controller.request.cookies
  4.       # 这个controller.request.cookies实际上是通过@cgi.cookies.freeze进行获取的
  5.       super()
  6.       update(@cookies)
  7.     end
  8.     # Returns the value of the cookie by +name+, or +nil+ if no such cookie exists.
  9.     def [](name)
  10.       # 到@cookies里面获取
  11.       cookie = @cookies[name.to_s]
  12.    # 如果包含value方法,如果里面大于1,那么就返回整个列表,否则返回第一个值
  13.       if cookie && cookie.respond_to?(:value)
  14.         cookie.size > 1 ? cookie.value : cookie.value[0]
  15.       end
  16.     end
  17.     # Sets the cookie named +name+. The second argument may be the very cookie
  18.     # value, or a hash of options as documented above.
  19.     def []=(name, options)
  20.       # 赋值操作
  21.       if options.is_a?(Hash)
  22.         # 如果是一个hash,那么下面这句话就是将所有的key都转化为String类型
  23.         # 将这个值的key设置为 name.to_s, 
  24.         options = options.inject({}) { |options, pair| options[pair.first.to_s] = pair.last; options }
  25.         options["name"] = name.to_s
  26.       else
  27.         options = { "name" => name.to_s, "value" => options }
  28.       end
  29.       set_cookie(options)
  30.     end
  31.     # Removes the cookie on the client machine by setting the value to an empty string
  32.     # and setting its expiration date into the past. Like <tt>[]=</tt>, you can pass in
  33.     # an options hash to delete cookies with extra data such as a <tt>:path</tt>.
  34.     def delete(name, options = {})
  35.       options.stringify_keys!
  36.       # 如果删除将这个key对应的值清空,并且将cookie设置为过期以更新
  37.       set_cookie(options.merge("name" => name.to_s, "value" => """expires" => Time.at(0)))
  38.     end
  39.     private
  40.       # Builds a CGI::Cookie object and adds the cookie to the response headers.
  41.       #
  42.       # The path of the cookie defaults to "/" if there's none in +options+, and
  43.       # everything is passed to the CGI::Cookie constructor.
  44.       def set_cookie(options) #:doc:
  45.         options["path"] = "/" unless options["path"] #默认路径设置为'/'
  46.         cookie = CGI::Cookie.new(options)
  47.         @controller.logger.info "Cookie set: #{cookie}" unless @controller.logger.nil?
  48.         @controller.response.headers["cookie"] << cookie #将cookie设置到response里面
  49.       end
  50.   end
再看看CGI::Cookie本身

CGI::Cookie的Attributes包括:

domain [RW] 
expires [RW] 
name [RW] 
path [RW] 
secure [R] 
value [RW]


name:the name of the cookie. Required.
value:the cookie‘s value or list of values.
path:the path for which this cookie applies. Defaults to the base directory of the  CGI  script.
domain:the domain for which this cookie applies.
expires:the time at which this cookie expires, as a  Time  object.
secure:whether this cookie is a secure cookie or not (default to false). Secure cookies are only transmitted to HTTPS servers.


Examples of use
  1.   cookie1 = CGI::Cookie::new("name""value1""value2", ...)
  2.   cookie1 = CGI::Cookie::new("name" => "name""value" => "value")
  3.   cookie1 = CGI::Cookie::new('name'    => 'name',
  4.                              'value'   => ['value1''value2', ...],
  5.                              'path'    => 'path',   # optional
  6.                              'domain'  => 'domain'# optional
  7.                              'expires' => Time.now, # optional
  8.                              'secure'  => true      # optional
  9.                             )
  10.   cgi.out("cookie" => [cookie1, cookie2]) { "string" }
  11.   name    = cookie1.name
  12.   values  = cookie1.value
  13.   path    = cookie1.path
  14.   domain  = cookie1.domain
  15.   expires = cookie1.expires
  16.   secure  = cookie1.secure
  17.   cookie1.name    = 'name'
  18.   cookie1.value   = ['value1''value2', ...]
  19.   cookie1.path    = 'path'
  20.   cookie1.domain  = 'domain'
  21.   cookie1.expires = Time.now + 30
  22.   cookie1.secure  = true

Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐