【发布时间】:2011-05-24 19:11:53
【问题描述】:
由于我的本地 IP 地址是 127.0.0.1,因此我无法让地理编码器正常工作,因此它无法正确定位到我所在的位置。
request.location.ip 显示“127.0.0.1”
我如何使用不同的 ip 地址(我的互联网连接 ip),这样它会带来更多相关数据?
【问题讨论】:
标签: ruby-on-rails ruby geocode
由于我的本地 IP 地址是 127.0.0.1,因此我无法让地理编码器正常工作,因此它无法正确定位到我所在的位置。
request.location.ip 显示“127.0.0.1”
我如何使用不同的 ip 地址(我的互联网连接 ip),这样它会带来更多相关数据?
【问题讨论】:
标签: ruby-on-rails ruby geocode
使用 MiddleWare 是一种很好的干净方式。将此类添加到您的 lib 目录:
# lib/spoof_ip.rb
class SpoofIp
def initialize(app, ip)
@app = app
@ip = ip
end
def call(env)
env['HTTP_X_FORWARDED_FOR'] = nil
env['REMOTE_ADDR'] = env['action_dispatch.remote_ip'] = @ip
@status, @headers, @response = @app.call(env)
[@status, @headers, @response]
end
end
然后找到您要用于开发环境的 IP 地址并将其添加到您的 development.rb 文件中:
config.middleware.use('SpoofIp', '64.71.24.19')
【讨论】:
1.1.2 我今天安装的版本是 1.1.6 所以这些版本中一定发生了一些变化
location 方法选择,并且由地理编码器执行对 nil 的搜索。在我的情况下评论该行有效。
env['HTTP_X_FORWARDED_FOR'] = nil 行就可以了。
.rvm/gems/ruby-2.0.0-p247/gems/activesupport-4.0.0.rc1/lib/active_support/inflector/methods.rb:226:in 'const_get': uninitialized constant SpoofIp (NameError)
为此,我通常使用params[:ip] 或正在开发的东西。这让我可以测试其他 IP 地址的功能并假装我在世界任何地方。
例如
class ApplicationController < ActionController::Base
def request_ip
if Rails.env.development? && params[:ip]
params[:ip]
else
request.remote_ip
end
end
end
【讨论】:
我的实现略有不同,这对我的情况很有效。
在application_controller.rb 中,我有一个查找方法,它调用地理编码器 IP 查找,直接传入 request.remote_ip 的结果。
def lookup_ip_location
if Rails.env.development?
Geocoder.search(request.remote_ip).first
else
request.location
end
end
然后在config/environments/development.rb 我猴子修补了remote_ip 调用:
class ActionDispatch::Request
def remote_ip
"71.212.123.5" # ipd home (Denver,CO or Renton,WA)
# "208.87.35.103" # websiteuk.com -- Nassau, Bahamas
# "50.78.167.161" # HOL Seattle, WA
end
end
我只是硬编码了一些地址,但你可以在这里做任何你想做的事情。
【讨论】:
request.location 正常工作,我必须修改这个答案,将 lookup_ip_location 方法重命名为 location 并将其放在 ActionDispatch::Request 类中。
我也有同样的问题。这是我使用地理编码器实现的方法。
#gemfile
gem 'httparty', :require => 'httparty', :group => :development
#application_controller
def request_ip
if Rails.env.development?
response = HTTParty.get('http://api.hostip.info/get_html.php')
ip = response.split("\n")
ip.last.gsub /IP:\s+/, ''
else
request.remote_ip
end
end
#controller
ip = request_ip
response = Geocoder.search(ip)
(来自 geo_magic gem 的 hostip.info 代码部分,并基于此问题的其他答案。)
现在您可以执行response.first.state 之类的操作
【讨论】:
这是地理编码器 1.2.9 的更新答案,为开发和测试环境提供硬编码 IP。只需将其放在config/initilizers/geocoder.rb 的底部即可:
if %w(development test).include? Rails.env
module Geocoder
module Request
def geocoder_spoofable_ip_with_localhost_override
ip_candidate = geocoder_spoofable_ip_without_localhost_override
if ip_candidate == '127.0.0.1'
'1.2.3.4'
else
ip_candidate
end
end
alias_method_chain :geocoder_spoofable_ip, :localhost_override
end
end
end
【讨论】:
alias_method_chain 在 Rails 5 中已被弃用,所以这个答案不再实际
你也可以这样做
request.safe_location
【讨论】:
request.location 相同的结果。你看到了什么不同?