【问题标题】:How does web page redirect work in this page?网页重定向如何在此页面中工作?
【发布时间】:2013-08-15 02:36:19
【问题描述】:

我正在尝试从此页面检索链接:http://www.seas.harvard.edu/academics/areas

页面中间有一个名为“计算机科学”的链接。其基础链接为“/academics/areas/computer-science”。我可以使用 Java 内置 URL 类将其转换为绝对 URL,获得“http://www.seas.harvard.edu/academics/areas/computer-science”。

但是,当我在 Chrome 浏览器中单击该链接时,绝对 URL 变为“http://www.seas.harvard.edu/computer-science”。

所以我的问题有两个:

  1. 此页面中的 URL 重定向如何工作?
  2. Java 中是否有任何库或方法可以帮助我在重定向后获取 URL?

我需要在重定向后获取 URL,因为我想阅读页面的源代码,但重定向前的 URL 对我不起作用。我正在使用JSoup 库来读取 URL,所以我怀疑它可能是基于 javascript 的重定向。

【问题讨论】:

  • 1) 服务器最有可能通过 .htaccess 中的 mod_rewrite 或通过服务器端编程语言发送 301 HTTP 标头(永久重定向)。

标签: java javascript url redirect jsoup


【解决方案1】:

来自curl --dump-header [file] [URL] 的文件看起来像:

HTTP/1.1 301 Moved Permanently
Age: 0
Cache-Control: no-cache, must-revalidate, post-check=0, pre-check=0
Content-Type: text/html
Date: Tue, 13 Aug 2013 13:00:12 GMT
ETag: "1376398812"
Expires: Sun, 19 Nov 1978 05:00:00 GMT
Last-Modified: Tue, 13 Aug 2013 13:00:12 GMT
Location: http://www.seas.harvard.edu/computer-science
Server: nginx
Vary: Accept-Encoding
Via: 1.1 varnish
X-AH-Environment: prod
X-Cache: MISS
X-Drupal-Cache: MISS
X-Redirect-ID: 44
X-Varnish: 2704315535
transfer-encoding: chunked
Connection: keep-alive

如您所见,这是从服务器提供的 301 永久重定向。

获取数据:

您可以使用HttpURLConnection进行连接,但在连接之前,请调用myConn.setInstanceFollowRedirects(true)。遵循重定向,您可以获取输出流并读取它。

获取 URL 本身:

您可以使用HttpURLConnection 进行连接,但在连接之前,请致电myConn.setInstanceFollowRedirects(false)跟随重定向。这会将实际的 URL 保存在正确的位置。

这里的窍门是,出于某种奇怪的原因,HttpURLConnection 不允许通过 name 检索标头,除非您将其解析为日期。

因此,您将需要迭代一个整数,在建立连接后调用getHeaderFieldKey 并检查它是否等于Location,如果是,则使用相同的整数获取getHeaderField 以获取位置。烦人,我知道。但地点不是日期,这是 JRE 的疏忽。

【讨论】:

    【解决方案2】:

    我使用 Fiddler 进行调查,站点返回链接 http://www.seas.harvard.edu/academics/areas/computer-science HTTP 301 response code,执行重定向。

    我想获得真实的 URL。您应该对 harvard.edu Web 服务器执行真实请求并解析响应。 (重定向 URL 位于 HTTP Header 中的 Location 键中)。

    很抱歉您的第二个问题。我没有Java技能。

    这个 SO 问题可能会有所帮助 (httpclient-4-how-to-capture-last-redirect-url)

    【讨论】:

      【解决方案3】:
      1. 可能有例如.htaccessmod_rewrite 重定向。使用 Firefox 的控制台我可以看到请求。正如您在下面看到的,服务器正在发回301 Moved Permanently 消息。这告诉浏览器重定向到响应的Location 标头中返回的地址。
      2. 获取更改后的 URL 的方式取决于加载页面的方式:
        • 如果您使用现成的库和代码将页面加载到例如一个 DOM 对象,你可以使用准备好的 HTTP 系统来加载响应,这可能会导致它自动重定向 -> 你将从加载页面的 URL 中获取 URL。如果它没有这样做,那么您必须检查状态代码 301 或 302,当收到这些状态代码时,更改后的 URL 位于响应的 Location 标头中。
        • 如果您编写了自己的代码来通过 TCP 套接字加载响应,那么您必须照常加载响应,但再次检查 301 和 302 状态代码并按照上一节中的说明进行操作。

      【讨论】:

        【解决方案4】:

        我只能尝试解决 Q1,因为我不是 Java 程序员。源代码说他们正在使用 Drupal,所以我推测他们正在使用 Drupal 的 global redirect module(关于 Drupal 重定向模块 here 的讨论)。查看模块的文档可能会对如何使用 Java 获取正确的 url 有所了解。

        在 javascript 中还有许多方法可以让 url 请求自动重定向到某个基本页面(例如 CS 主页),同时物理导航站点允许用户前进到新页面。这是许多单页 Web 应用程序中的标准做法。如果是这种情况,那么 @hexafraction 的建议可能能够帮助您检索所需的 url,尽管我不熟悉他建议的 Java 方法。

        【讨论】:

          【解决方案5】:

          您可以从下面的代码设置followRedirectsfalse 中获取Redirect URL

          如果您将重定向页面设置为true,您将获得重定向页面的源代码,这是Jsoup的默认行为

           Connection con = Jsoup.connect("http://www.seas.harvard.edu/academics/areas/computer-science")
                                        .userAgent("Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/27.0.1453.110 Safari/537.36")
                                        .followRedirects(false);
          
                     System.out.println("Redirected Url : " + con.execute().header("Location")); //null if followRedirect is true
          
                     Document doc = con.get();
                     System.out.println(doc.html());
                     System.out.println("=================================================");
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2019-08-22
            • 2017-11-03
            • 1970-01-01
            • 2023-04-05
            • 2013-08-18
            • 1970-01-01
            • 2012-09-22
            相关资源
            最近更新 更多