问题描述
我刚刚开始了我的第一个Sinatra项目,一个简单的电视节目管理网络应用程序,并希望拥有漂亮的网址。所以当一个用户输入搜索框并提交时,我不想要一个 /?search = foobar -style URL,并且要重定向到 /搜索/ foobar的。这也使我能够从主要的 get'/'路由分离 get'/ search /:name 路由。我在过滤器之前使用实现了重定向,并正确地转义了 params [] 变量:
before do
if params.has_key? 'search'
redirect to(/ search /#{URI.escape(params ['search'])})
end
end
然后我继续
/ search /:query'do
result = search_api params [:query]
if result =='null'
#no results
else
result = JSON。解析(结果)
如果result.key? '显示'
#显示搜索结果
else
#重定向到一个单独的显示
#(result.keys).first是提供的显示的真实名称
#由api。它可能包含特殊字符
#
#(result.keys).first#=> 打破坏
#result.keys#=> 打破坏
#result.key? Breaking Bad#=> true
redirect to('/ show /#{URI.escape((result.keys).first)}')
end
end
end
不幸的是,重定向到 / show 页面只能工作,如果有除了%之外的名称中没有URI特殊字符。这也意味着没有空格。当我搜索空间或变音符或任何东西的东西,例如 GET for /?search = Breaking%20Bad ,我从Sinatra / Rack得到以下错误:
[2013-02-02 00:30:29]错误URI :: InvalidURIError:bad URI(is不是URI?):http:// localhost:9393 / show / Breaking Bad
/Users/Ps0ke/.rvm/rubies/ruby-1.9.3-p194/lib/ruby/1.9.1/uri/generic .rb:1202:在rescue in merge
/Users/Ps0ke/.rvm/rubies/ruby-1.9.3-p194/lib/ruby/1.9.1/uri/generic.rb:1199:in `merge'
/Users/Ps0ke/.rvm/rubies/ruby-1.9.3-p194/lib/ruby/1.9.1/webrick/httpresponse.rb:220:in`setup_header'
/用户/ Ps0ke / .rvm / rubies / ruby-1.9.3-p194 / lib / ruby / 1.9.1 / webrick / httpresponse.rb:150:在`send_response'
/Users/Ps0ke/.rvm/rubies $ r $ $ /lib/ruby/1.9.1/webrick/server.rb:191:in`start_thread'中的块
浏览器显示我,那是g ot重定向到 / search / Breaking%20Bad ,所以第一个重定向工作。这个错误只发生在搜索产生确切命中时,所以重定向的问题是在 get'/ search /:query'路由中搜索。我记得它工作了一次,但是在我的git历史中找不到正确的提交。
我正在运行
%gem list sinatra
sinatra(1.3.4,1.3.3)
%gem list rack
机架(1.4.4,1.4.1)
机架缓存(1.2)
rack-flash3(1.0.3)
机架保护(1.3.2,1.2.0 )
rack-ssl(1.3.2)
机架测试(0.6.2,0.6.1)
也许有人可以告诉我:
- 这是好还是坏的做法/还有另一种方法在sinatra到prettifiy URL
- 如何解决这个问题,因为我认为我已经逃脱了所有的细节
非常感谢你提前:)
在行
redirect to('/ show /#{URI.escape((result.keys).first)}')
pre>
您正在使用单引号。这意味着不执行字符串插值,因此文字字符串 / show /#{URI.escape((result.keys).first)} 正被用作url,这就是为什么它是失败的。
为了插值工作,你需要使用这样的双引号:
redirect to(/ show /#{URI.escape((result.keys).first)})
pre>
这将导致#{URI.escape((result.keys).first)} 被替换与转义的电影名称,应该是一个有效的URL。
请注意,在您的第一个重定向,你使用双引号,所以它的工作原理:
redirect to(/ search /#{URI.escape(params ['search'])})
I've just started my first Sinatra project, a simple TV-show management web app, and wanted to have beautiful URLs. So when a user types in the search box and submits, I don't want to have a /?search=foobar-style URL and want do redirect them to /search/foobar. This also enables me to separate the get '/search/:name route from the main get '/' route. I've implemented the redirect using a before filter and properly escaped the params[] variable:
before do if params.has_key? 'search' redirect to("/search/#{URI.escape(params['search'])}") end endand later I continue with
get '/search/:query' do result = search_api params[:query] if result == 'null' # no results else result = JSON.parse(result) if result.key? 'shows' # display search results else # redirect to one single show # (result.keys).first is the real name of the show provided # by the api. It may contain special characters # # (result.keys).first #=> "Breaking Bad" # result.keys #=> "Breaking Bad" # result.key? "Breaking Bad" #=> true redirect to('/show/#{URI.escape((result.keys).first)}') end end endunfortunately, the redirect to the /show page only works, if there are no URI special characters in the name apart from %. This also means no spaces. When I search for something with a space or an umlaut or anything, e.g. a GET for /?search=Breaking%20Bad, I get the following error from Sinatra/Rack:
[2013-02-02 00:30:29] ERROR URI::InvalidURIError: bad URI(is not URI?): http://localhost:9393/show/Breaking Bad /Users/Ps0ke/.rvm/rubies/ruby-1.9.3-p194/lib/ruby/1.9.1/uri/generic.rb:1202:in `rescue in merge' /Users/Ps0ke/.rvm/rubies/ruby-1.9.3-p194/lib/ruby/1.9.1/uri/generic.rb:1199:in `merge' /Users/Ps0ke/.rvm/rubies/ruby-1.9.3-p194/lib/ruby/1.9.1/webrick/httpresponse.rb:220:in `setup_header' /Users/Ps0ke/.rvm/rubies/ruby-1.9.3-p194/lib/ruby/1.9.1/webrick/httpresponse.rb:150:in `send_response' /Users/Ps0ke/.rvm/rubies/ruby-1.9.3-p194/lib/ruby/1.9.1/webrick/httpserver.rb:110:in `run' /Users/Ps0ke/.rvm/rubies/ruby-1.9.3-p194/lib/ruby/1.9.1/webrick/server.rb:191:in `block in start_thread'The browser shows me, that it got redirected to /search/Breaking%20Bad, so the first redirect worked. This "bug" only occurs, when the search produces an exact hit, so the problem with the redirect is to search in the get '/search/:query' route. I remember that it worked once, but can't find the right commit in my git history.
I am running
% gem list sinatra sinatra (1.3.4, 1.3.3) % gem list rack rack (1.4.4, 1.4.1) rack-cache (1.2) rack-flash3 (1.0.3) rack-protection (1.3.2, 1.2.0) rack-ssl (1.3.2) rack-test (0.6.2, 0.6.1)Maybe someone of you can tell me:
- whether this is good or bad practices/there is another way in sinatra to prettifiy URLs
- how to fix this, since I think I have already escaped everything carefully
Thank you very much in advance :)
解决方案In the line
redirect to('/show/#{URI.escape((result.keys).first)}')you are using single quotes. This means that string interpolation isn’t performed, so the literal string /show/#{URI.escape((result.keys).first)} is being used as the url and that is why it is failing.
In order for interpolation to work you need to use double quotes like this:
redirect to("/show/#{URI.escape((result.keys).first)}")This will cause #{URI.escape((result.keys).first)} to be replaced with the escaped movie name, which should be a valid url.
Note that in your first redirect you do use double quotes, so it works as expected:
redirect to("/search/#{URI.escape(params['search'])}")
这篇关于Sinatra / Rack`ERROR URI :: InvalidURIError:重定向上的URI(不是URI?)`的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!