Sinatra / Rack`ERROR URI :: InvalidURIError:重定向上的URI(不是URI?)` [英] Sinatra/Rack `ERROR URI::InvalidURIError: bad URI(is not URI?)` on redirect
问题描述
我刚刚开始了我的第一个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 theget '/search/:name
route from the mainget '/'
route. I've implemented the redirect using abefore
filter and properly escaped theparams[]
variable:before do if params.has_key? 'search' redirect to("/search/#{URI.escape(params['search'])}") end end
and 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 end
unfortunately, 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. aGET
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 theget '/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?)`的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!