【问题标题】:Geocoder, how to test locally when ip is 127.0.0.1?Geocoder,当ip为127.0.0.1时如何在本地测试?
【发布时间】: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


    【解决方案1】:

    使用 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')
    

    【讨论】:

    • 可能是一个菜鸟点,但是您必须在例如 config/application.rb 中添加一些东西来自动加载该类,例如:config.autoload_paths += Dir["#{config.root}/ lib/**/"]
    • 我很久以前就尝试过这种方法,效果惊人。最近在另一个应用程序上再次尝试没有工作。大约 2 小时后,我尝试降级地理编码器的版本......它成功了!我最初使用的地理编码器版本是 1.1.2 我今天安装的版本是 1.1.6 所以这些版本中一定发生了一些变化
    • @DickieBoy,你是对的,由于以下change,该方法不适用于 Geocoder 1.1.6。该解决方案使 env['HTTP_X_FORWARDED_FOR'] = nil,但它不会从哈希中删除密钥,因此它被location 方法选择,并且由地理编码器执行对 nil 的搜索。在我的情况下评论该行有效。
    • FWIW 我可以使用 Geocoder 1.1.8 gem 确认@deivid 对 Rails 4.0.0 的上述修复。按照@Ruckstar 的回答并注释掉env['HTTP_X_FORWARDED_FOR'] = nil 行就可以了。
    • 它对我不起作用,无论是否注释掉 Jason 行,我都会遇到以下错误:.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)
    【解决方案2】:

    为此,我通常使用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
    

    【讨论】:

    • 我不熟悉“地理编码器”,我认为它是一个宝石或其他东西,但我想有一些方法可以配置它。我使用 GeoIP 进行地理编码:geoip.rubyforge.org,使用这种方法很容易使用。
    • 你是在开发环境中,所以没有办法使用真实的请求ip地址。您需要找到某种方式告诉“地理编码器”在开发中它应该使用另一个值。
    【解决方案3】:

    我的实现略有不同,这对我的情况很有效。

    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 类中。
    【解决方案4】:

    我也有同样的问题。这是我使用地理编码器实现的方法。

    #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 之类的操作

    【讨论】:

      【解决方案5】:

      这是地理编码器 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 中已被弃用,所以这个答案不再实际
      【解决方案6】:

      你也可以这样做

      request.safe_location
      

      【讨论】:

      • 这对我来说返回与request.location 相同的结果。你看到了什么不同?
      猜你喜欢
      • 2020-02-18
      • 2014-08-19
      • 1970-01-01
      • 1970-01-01
      • 2012-04-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多