Sinatra / Rack`ERROR URI :: InvalidURIError:重定向上的URI(不是URI?)` [英] Sinatra/Rack `ERROR URI::InvalidURIError: bad URI(is not URI?)` on redirect

查看:205
本文介绍了Sinatra / Rack`ERROR URI :: InvalidURIError:重定向上的URI(不是URI?)`的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我刚刚开始了我的第一个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)

也许有人可以告诉我:


  1. 这是好还是坏的做法/还有另一种方法在sinatra到prettifiy URL

  2. 如何解决这个问题,因为我认为我已经逃脱了所有的细节

非常感谢你提前:)

解决方案

在行

  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
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. 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:

  1. whether this is good or bad practices/there is another way in sinatra to prettifiy URLs
  2. 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屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆