【问题标题】:What's the best way to redirect a URL when developing on localhost?在 localhost 上开发时重定向 URL 的最佳方法是什么?
【发布时间】:2016-12-07 22:53:24
【问题描述】:

问题:

我有两个网络应用程序,“App1”通过 ajax 从“App2”获取数据。在生产中,App1 应该从 App2 的生产 url 获取数据。但是,当我在 localhost:3000 上开发 App1 时,我希望 App1 从 localhost:3001 的本地版本的 App2 获取数据(而不是从生产版本)。

先前的研究:

我已经搜索了很多关于如何做到这一点,但不能真正对我找到的东西做出正面或反面。

  • 我已经阅读了一些建议我应该更改 /etc/hosts 的内容,但由于生产站点使用 HTTPS 而我的 localhost 只是 HTTP,因此我无法使其正常工作。

  • 我也遇到过 .htaccess,但添加文件似乎没有任何效果,我在 Apache 兔子洞中迷失了方向,只是在寻找如何打开 .htaccess 的东西. (我也看过一些关于 mod-rewrite 的东西,但也不知道如何让它发挥作用。)

  • 我还发现了像 Switcheroo Redirector 这样的 Chrome 扩展程序,但这并没有很好地工作,因为简单的重定向会将一些基本的 HTTP 响应更改为 301,而我的应用程序无法处理这些响应。

问题

  • 对于我正在尝试做的事情,什么是正确的工具? (/etc/hosts、.htaccess 或其他)

  • 要获得所需结果,该工具的最基本配置是什么?

【问题讨论】:

  • 您必须以某种方式更改 app1 实际请求的 URL。没办法。通常,这样的 URL(至少是基本 URL)是应用程序的配置参数,而不是硬编码在路径中。所以你可以把它放在一个配置文件中,或者更优雅地把它作为环境变量从 http 服务器交给 php 脚本。然后,只有这样,您才能获得所需的所有重写方法。但没有它,请求甚至不会到达您的本地 http 服务器,这意味着所有尝试做任何事情都没有任何效果。
  • 好的,很高兴知道。谢谢!
  • 啊,一种选择确实是修改本地主机名配置以将该生产系统名称解析为本地地址。然后,您必须在本地 http 服务器中使用本地生产系统名称配置虚拟主机,并使用自签名证书打开 https。这应该可行,只有您的应用需要接受这样的 https 连接自签名证书,所以证书验证应该被关闭。
  • 另外,@arkascha 如果您将您的回复复制为答案(不是评论),我可以接受并关闭此问题。
  • 不确定这是否已经解决了您的问题。这就是我发表评论的原因;-)

标签: .htaccess mod-rewrite url-rewriting localhost url-redirection


【解决方案1】:

通常您想更改 app1 实际请求的 URL。通常这样的 URL(至少是基本 URL)是应用程序的配置参数,不是硬编码的。所以你可以把它放在一个配置文件中,或者更优雅地把它作为环境变量从 http 服务器交给 php 脚本。然后,只有这样,您才能获得所需的所有重写方法。但没有它,请求甚至不会到达您的本地 http 服务器,这意味着所有尝试做任何事情都没有任何效果。

然而,另一种选择是修改本地主机名配置,以将该 app2 生产系统名称解析为本地 IP 地址。然后,您必须使用生产系统名称在本地 http 服务器中配置虚拟主机并打开 https。您可以使用自签名证书进行 ssl 加密。这应该可以,只有您的应用程序需要接受这样的自签名证书以进行 https 连接,因此应该关闭证书验证。

【讨论】:

    【解决方案2】:

    我会用 jquery 做一个简单的请求,如下所示。通过查询http://api.jquery.com/jquery.ajax/查看查询Ajax请求的更多信息

    var url = "localhost:3001/cart/1";
     $.ajax({
                url: url,
                data: currentQueryData,
                success: function(data) {
                  console.log("Data from App2 url: + data);
                  // Do something with your data
                },
                failure: function(error){
                    console.log(error);
                }
            });
    

    当您将开发的应用程序用于生产时,只需将属性 url 的值更改为“https://api.app2.com”,这样请求就会比生产 App2 发送。 您还可以通过编辑 /etc/hosts 配置文件并将此行添加到其中,将生产 url 指向您的本地主机:

    127.0.0.1 domain.app2.de
    

    但您仍需要在您的 javascript 文件中将端口添加到该域。喜欢

    var url = "domain.app2.de:3001"
    

    因为您无法将域绑定到 /etc/hosts 文件中的特定端口。 所以像下面这样的东西是行不通的!

    127.0.0.1:3001 domain.app2.de  # not working
    

    希望对您有所帮助。我建议也将入口点 url 存储到您的 app2 的配置中。将其存储在 javascript 值中只是为了展示如何将其作为简单示例完成的目的。否则,如果您可以提供一个您想从 app2 获取的示例,那就太好了。

    【讨论】:

      【解决方案3】:

      我会使用mod_proxy + mod_rewrite,这样所有在主域上具有单个路径前缀的 URL 都会在内部重写为对 app2 的代理请求。这有几个优点:

      1. 您不会用服务器配置污染您的前端。这样可以很好地分离关注点,并确保代码在 dev 和 live 之间没有差异。
      2. 没有 CORS 问题,因为对于客户端,所有请求都发送到相同的方案、域和端口。
      3. Ajax URL 更简洁,因为它们可以是根相关的。 (您的所有网址都应该如此。)
      4. 您可以在开发服务器和实时服务器上使用相同的、未修改的.htaccess 文件,因为它可以根据发送的主机标头有条件地重写每个 app2。 (尽管如果您可以访问它,您应该将配置放入您的虚拟主机中。)
      5. 您可以使用相同的条件逻辑仅在现场强制执行 https。 (不要在应用代码中这样做。)
      6. 您可以通过编辑单个规则切换到不同的 app2 服务器进行重定位/升级,而不会中断用户。

      假设您在 .htaccess 中执行此操作

      RewriteEngine on
      # force https and single domain on live
      RewriteCond %{HTTP_HOST} !=localhost
      RewriteCond %{HTTP_HOST} ^(?!real-app1\.com$). [NC,OR]
      RewriteCond %{HTTPS} =off
      RewriteCond %{THE_REQUEST} ^\S+\s+/(\S*)
      RewriteRule ^ https://real-app1.com/%1 [NS,NE,L,R=301]
      # API proxy on dev
      RewriteCond %{HTTP_HOST} =localhost
      RewriteCond %{THE_REQUEST} ^\S+\s+/API(?:/(\S*))?
      RewriteRule ^API(?:$|/) http://localhost:3001/%1 [NS,NE,P]
      # API proxy on live (no need for hostname check)
      RewriteCond %{THE_REQUEST} ^\S+\s+/API(?:/(\S*))?
      RewriteRule ^API(?:$|/) https://real-app2.com/%1 [NS,NE,P]
      

      然后,在您的前端,普通链接可以是 <a href="/foo/bar/">…,假设您使用的是库,ajax 可以像这样简单:

      $.ajax('/API/path/to/endpoint/', {
          data: {
              query_param: 'param_value'
          }
      })
      .done(function() {
          // API works
      })
      .fail(function() {
          // oh dear
      });
      

      在那里,app2 应该收到http://localhost:3001/path/to/endpoint/?query_param=param_value。正确设置的工作量少于在应用程序生命周期内管理配置和部署问题的麻烦。绝对值得。

      【讨论】:

        猜你喜欢
        • 2014-06-07
        • 1970-01-01
        • 2011-02-15
        • 1970-01-01
        • 2012-01-08
        • 1970-01-01
        • 1970-01-01
        • 2010-10-29
        • 1970-01-01
        相关资源
        最近更新 更多