Sinatra饼干没有按预期行事

时间:2014-07-16 13:43:16

标签: ruby sinatra

before %(/(..)/.*) do
    lang = params[:captures].first
    cookies[:lang] = lang
    p cookies
end

get '/' do
    p cookies
end

上述代码应在任何请求lang上设置带有两个字符值的cookie /xx/*,其中xx是任意两个字符串。这可以按预期工作,因为导航/es/login将输出<#Sinatra::Cookies::Jar: "ASP.NET_SessionId"=>"*snip*", "lang"=>"es">

如果我立即导航到/,则输出<#Sinatra::Cookies::Jar: "ASP.NET_SessionId"=>"..", "lang"=>"en">

出于多种原因,这很奇怪,最值得注意的是我从未导航到/en/*。我假设cookies[:lang]没有正确设置Cookie,en是一个在过去的某个时间正确设置为lang的值,但我不知道任何方法检查,或修复它。

我应该注意到这是我触摸项目中cookies对象的唯一地方。

初始化文件的片段:

require 'sinatra/base'
require 'sinatra/cookies'
...
class Site < Sinatra::Application
    helpers Sinatra::Cookies
    ...
end

1 个答案:

答案 0 :(得分:2)

事实证明,cookie是路径特定的。

例如,/en/login会拥有适用于/en/login/*的Cookie集,而/会有适用于/*的Cookie。因此,通过在cookies[:lang]中设置before %r(/(..)/.*),我只为任何路由/xx/*设置了Cookie。

我通过使用Sinatra的response.set_cookie方法解决了这个问题,这使我可以明确地将路径设置为/。我也可以将Cookies gem的默认设置设置为/,但我认为这是一个糟糕的主意。

sinatra#set_cookie的解决方案:

before $(/(..)/.* do
    lang = params[:captures].first
    response.set_cookie(:lang, lang)
end

通过设置Cookies

的默认值来解决问题
require 'sinatra/base'
require 'sinatra/cookies'
...
def Site < Sinatra::Application
    helpers Sinatra::Cookies
    configure do
        set :cookie_options, domain: nil
    end
    ...
end