2013-02-01 114 views
1

我刚开始我的第一个项目西纳特拉,一个简单的电视节目管理的Web应用程序,并希望有美丽的网址。因此,当在搜索框中输入一个用户类型和提交,我不希望有一个/?search=foobar风格的URL,并希望做他们重定向到/search/foobar。这也使我的get '/search/:name路线从主get '/'路线分开。我实现了使用before过滤器重定向并正确地躲过了params[]变量:西纳特拉/机架`ERROR URI :: InvalidURIError:坏URI(是不是URI?)`对重定向

before do 
    if params.has_key? 'search' 
     redirect to("/search/#{URI.escape(params['search'])}") 
    end 
end 

,后来我继续

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 

不幸的是,重定向到一个页面/show才能正常运行,如果有在远离%名字没有URI特殊字符。这也意味着没有空间。当我搜索空间或元音变音或其他东西时,例如为/?search=Breaking%20Bad一个GET,我从西纳特拉/机架收到以下错误:

[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' 

浏览器显示我,它得到重定向到/search/Breaking%20Bad,所以第一个重定向工作。这个“错误”只发生,当搜索产生精确打击,所以用重定向的问题是在get '/search/:query'路线进行搜索。我记得它曾经工作过,但在我的git历史中找不到正确的提交。

我正在

% 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) 

也许你有人能告诉我:

  1. 这是好还是坏的做法/存在西纳特拉另一种方式prettifiy网址
  2. 如何解决这个问题,因为我认为我已经逃脱了一切仔细

谢谢v ERY提前:)

+0

只是为了澄清,这将是(例如)调用'result.keys'的结果呢? “绝命毒师” ?并请加西纳特拉的版本和机架你使用。 – iain

回答

2

多,在线路

redirect to('/show/#{URI.escape((result.keys).first)}') 

使用的是单引号。这意味着,不执行字符串插值,所以文字串/show/#{URI.escape((result.keys).first)}被用作URL,这就是为什么它是失败的。

为了插工作,你需要用双引号是这样的:

redirect to("/show/#{URI.escape((result.keys).first)}") 

这将导致#{URI.escape((result.keys).first)}与逃脱的电影名称,这应该是一个有效的URL来代替。

注意,在你的第一个重定向你使用双引号,所以它按预期工作:

redirect to("/search/#{URI.escape(params['search'])}") 
+0

噢,我的,这是尴尬!您调试为我们一些时间,而忽略了木材的树木。谢谢。 – Ps0ke

+0

某些文本编辑器(如Sublime Text)会以不同颜色突出显示插值部分(如果您使用双引号),以便您可以看到它将被插值。 –

相关问题