使用Rails重定向到外部URL不起作用

时间:2014-01-16 08:10:56

标签: ruby-on-rails ruby-on-rails-3 redirect

在控制器中我尝试

redirect_to @url

@url是一个格式正确的https网址

当我这样做时,浏览器中没有任何事情发生

日志显示有重定向,但在chrome检查中我看到了

Request URL:https://..myurl...
Request Headers CAUTION: Provisional headers are shown.
Origin:http://localhost:3000
Referer:http://localhost:3000/cars/105
User-Agent:Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/32.0.1700.76 Safari/537.36
Query String Parametersview sourceview URL encoded
tId:6f6bfeaf-fd47-42ae-8e43-6b7118d21b0b

网络标签显示已取消..

我错过了什么吗?为什么不进行重定向?

7 个答案:

答案 0 :(得分:1)

根据您在Chrome中的网络标签中看到请求已取消的声明,听起来您正试图在AJAX请求中执行此操作。默认情况下不支持跨域AJAX请求。如果您可以控制https://..myurl...应用,则可以实施CORSJSONP

修改

您在其中一条评论中提到的第三种方法是通过在客户端重定向, AJAX之后绕过对AJAX请求的跨站点重定向的限制请求完成(通过设置window.location)。但是,如果您的最终目标是让重定向透明地发生 - 作为AJAX请求的一部分而不是之后 - 您将需要实现CORS或JSONP。

答案 1 :(得分:0)

您是否可以访问该页面并在Chrome中看到它而没有任何安全警告?

我有css等没有加载,因为我是通过https向具有未经验证的证书的本地服务器请求它。 Chrome可能会在进入网址之前在幕后进行检查,但我肯定不知道。

尝试redirect_to https://www.google.com并查看是否有效。

答案 2 :(得分:0)

我认为您需要指定要使用的协议使用SSL。 ActionController::Base#redirect_to方法采用选项哈希,其中一个参数是:protocol,允许您定义:

redirect_to :protocol => 'https://'

如果您要通过SSL完成所有重定向,则将其放入控制器中的before_action是有意义的。您可以定义一个方法:

def redirect_via_https
  redirect_to :protocol => "https://" unless (request.ssl? || request.local?)
end

并将其添加到您的控制器:

class SpecificController
    before_action :redirect_via_https
end

答案 3 :(得分:0)

你的rails版本是什么,因为redirect_to方法适用于外部网址。

class HomeController < ApplicationController
  def index
  @url = "https://facebook.com"
  redirect_to @url
end

有效。

答案 4 :(得分:0)

搜索一段时间后(注意:显示临时标题) 我认为它与一些Chrome扩展程序有关,例如广告拦截器或网络内部 引用another stackoverflow question“消息在那里,因为从未发出检索该资源的请求,因此显示的标题不是真实的。正如您引用的问题中所解释的那样,当服务器响应时,真实标题会更新,但如果请求被阻止,则无响应。“

您可以确保禁用所有能够阻止请求的扩展程序并再次尝试。

答案 5 :(得分:0)

我会建议几个问题排查步骤:

  • 尝试其他浏览器(Safari,Firefox),如果它在该浏览器上运行,那么Chrome扩展程序可能阻止您访问该重定向的网址。
  • 尝试重定向到其他网址,尝试使用和不使用https。
  • 检查您的Rails操作是否是AJAX调用。如果是ajax请求,则redirect_to将无效。

答案 6 :(得分:0)

我认为围绕AJAX的怀疑是有根据的。考虑到我们所呈现的应用程序的狭隘视图,很难猜测可能会发生什么。尝试更改

redirect_to @url

if request.xhr?
  render :update do |page|
    page.redirect_to @url
  end
else
  redirect_to @url
end

另外,考虑到重定向,@url可能具有超出范围。您最有可能同样有效地使用url

修改:

根据我之前忽略的信息,我确信以前的解决方案会纠正这个问题。基本上,一些浏览器更严格地处理它们如何处理对xhr请求的响应。使用标准的redirect_to,您可以为xhr请求发送“常规”响应。即使你有一个通常包含重定向代码的* .js.rjs或* .js.erb,也会发生这种情况,因为redirect_to调用将阻止该代码被执行。如果你的应用程序的js优雅地降级,那么你很可能迟早会遇到这个问题,因为你似乎有几次。我找到了几种处理基本问题的好方法。

选项1:

一种方法是简单地将重定向调整为如下所示:redirect_to( @url ) unless request.xhr?,然后将适当的重定向逻辑添加到* .js.erb文件中。除了重定向之外,如果您还需要运行其他javascript,则此方法很好。

选项2:

另一个运行良好的解决方案是向应用程序控制器添加类似的内容:

def redirect_to(args)
  if request.xhr?
    render js: "window.location = '#{ _compute_redirect_to_location args }'"
  else
    super args
  end
end

这很好,因为您不需要筛选和修改现有代码,它只是开始在任何地方工作。另一个好处是你仍然可以将重定向限定为前一个选项,以允许更复杂的javascript。你甚至可以疯狂地添加一些额外的应用程序特定选项,如flash消息,如果你想进一步扩展方法并真正使它适合你。

选项3:

如果您没有覆盖现有方法,可以添加以下内容:

def firm_redirect_to(url)
  if request.xhr?
    render js: "window.location = '#{ url }'"
  else
    redirect_to url
  end
end

但是你必须修改所有代码。

我个人更喜欢选项2的变体...无论如何,希望这会有所帮助 - 祝你好运。