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
答案 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