【问题标题】:How to check if page exists using JavaScript如何使用 JavaScript 检查页面是否存在
【发布时间】:2011-04-24 19:00:52
【问题描述】:

我有一个链接:<a href="http://www.example.com">Hello</a>

当有人点击链接时,我想通过 JavaScript 检查 href 属性指向的页面是否存在。如果页面存在,浏览器将重定向到该页面(本例中为“www.example.com”),但如果该页面不存在,浏览器应重定向到另一个 URL。

【问题讨论】:

  • 请定义“有效”。这个词可以有多种含义。
  • 您需要详细说明您的问题 - 尽可能准确并举例说明。
  • 所以你想检查一个页面是否存在?如果它不使用javascript?用什么?
  • 没有愚蠢的问题,只有犹豫不决的人

标签: javascript hyperlink


【解决方案1】:

这取决于页面是否存在于同一个域中。如果您试图确定外部域上的页面是否存在,它将无法工作——浏览器安全性会阻止跨域调用(同源策略)。

如果它在同一个域上但是,你可以像 Buh Buh 建议的那样使用 jQuery。尽管我建议执行 HEAD 请求而不是 GET 请求,但默认的 $.ajax() 方法会执行 - $.ajax() 方法将下载整个页面。执行 HEAD 请求只会返回标题并指示页面是否存在(响应代码 200 - 299)或不存在(响应代码 400 - 499)。示例:

$.ajax({
    type: 'HEAD',
    url: 'http://yoursite.com/page.html',
success: function() {
        // page exists
},
error: function() {
        // page does not exist
}
});

另请参阅:http://api.jquery.com/jQuery.ajax/

【讨论】:

  • 为什么这只能在域内实现?
  • @JensMander,正如答案所述,这是由于浏览器具有防止跨域调用的同源策略。 AFAIK,这个政策是为了防止 XSS 和其他安全漏洞。
【解决方案2】:

一个很好的解决方法是代理。如果您无权访问服务器端,则可以使用 YQL。访问:http://developer.yahoo.com/yql/console/

从那里您可以执行以下操作:select * from htmlstring where url="http://google.com"。您可以使用他们在该页面上的“REST 查询”作为代码的起点。

这里有一些代码可以接受完整的 URL 并使用 YQL 来检测该页面是否存在:

function isURLReal(fullyQualifiedURL) {
    var URL = encodeURIComponent(fullyQualifiedURL),
        dfd = $.Deferred(),
        checkURLPromise = $.getJSON('http://query.yahooapis.com/v1/public/yql?q=select%20*%20from%20htmlstring%20where%20url%3D%22' + URL + '%22&format=json');

    checkURLPromise
            .done(function(response) {
                // results should be null if the page 404s or the domain doesn't work
                if (response.query.results) { 
                    dfd.resolve(true);
                } else {
                    dfd.reject(false);
                }
            })
            .fail(function() {
                dfd.reject('failed');
            });

    return dfd.promise();
}

// usage
isURLReal('http://google.com')
        .done(function(result) {
            // yes, or request succeded
        })
        .fail(function(result) {
            // no, or request failed
        });

2017 年 8 月 2 日更新

看起来 Yahoo 已弃用“从 html 中选择 *”,尽管“从 htmlstring 中选择 *”确实有效。

【讨论】:

  • 这是一个很好的答案。但您必须注意,对于一个 robots.txt 包含“User-agent: * Disallow: /”的网站,此方法将“失败”(因为 Yahoo API 将返回空结果)。为了更安全,您必须查看“http-status-code”键值。
  • @BastienLibersa 我在哪里可以找到“http-status-code”?我没有在响应对象中找到它
  • 当查询失败时,它将成为“url”对象的一部分。示例:query.yahooapis.com/v1/public/yql?q=select%20*%20from%20html%20where%20url%3D%22wordpress.com%2Fwp-admin%2F%22&format=json&diagnostics=true&callback=
  • 这总是返回失败
  • @reggie yahoo 在 7 月初弃用了一些东西。现在替换一些代码。
【解决方案3】:

基于 XMLHttpRequest 的文档:

function returnStatus(req, status) {
  //console.log(req);
  if(status == 200) {
    console.log("The url is available");
    // send an event
  }
  else {
    console.log("The url returned status code " + status);
    // send a different event
  }
}

function fetchStatus(address) {
 var client = new XMLHttpRequest();
 client.onreadystatechange = function() {
  // in case of network errors this might not give reliable results
  if(this.readyState == 4)
   returnStatus(this, this.status);
 }
 client.open("HEAD", address);
 client.send();
}

fetchStatus("/");

但这仅适用于与当前 URL 位于同一域中的 URL。您希望能够 ping 外部服务吗?如果是这样,您可以在服务器上创建一个简单的脚本来为您完成工作,然后使用 javascript 来调用它。

【讨论】:

    【解决方案4】:

    如果在同一个域中,可以用 xmlhttprequest 对象 [ajax] 发起头部请求并检查状态码。

    如果它在另一个域中,则向服务器发出 xmlhttprequest 并让它进行调用以查看它是否已启动。

    【讨论】:

      【解决方案5】:

      为什么不在网络服务器上创建一个自定义的 404 处理程序?这可能是更“好熊”的方式。

      【讨论】:

        【解决方案6】:

        如果你乐于使用 jQuery,你可以做这样的事情。 当页面加载时,对每个链接进行 ajax 调用。然后只需替换所有失败的链接的href。

        <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4/jquery.min.js"></script> 
        <script type="text/javascript">
        <!--
        
        $.fn.checkPageExists = function(defaultUrl){
        
            $.each(this, function(){
        
                var $link = $(this);
        
                $.ajax({
                    url: $link.attr("href"),
                    error: function(){
                        $link.attr("href", defaultUrl);
                    }
                });
            });
        };
        
        $(document).ready(function(){
            $("a").checkPageExists("default.html");
        });
        //-->
        </script> 
        

        【讨论】:

        • 将其设置为 onClick 事件处理程序将减轻一直发出所有请求的负担,因此它只会检查用户何时单击链接(而不是始终检查所有链接),从而减少等待时间和流量
        • @Allbite 可以,但是用户必须单击链接并等待 ajax 请求结束。如果这很慢,那么链接可能只是损坏了。
        • 这可能是一个糟糕的解决方案,因为它需要在页面就绪时发出许多请求。最好在点击时进行检查,因为只需要检查一个。如果HREF 指向外部域,所有链接都将获得其他页面地址。
        【解决方案7】:
        $.ajax({
                url: "http://something/whatever.docx",
                method: "HEAD",
                statusCode: {
                    404: function () {
                        alert('not found');
                    },
                    200: function() {
                    alert("foundfile exists");
                }
                }
            });
        

        【讨论】:

        • 这似乎是唯一有效的解决方案。为什么它被否决?可能是作者和我有同样的错误想法。如果可能的话,也许有人可以详细说明。
        • 这可能是因为作者没有用散文详细说明代码。
        【解决方案8】:

        由于同源政策,您将无法使用 ajax 调用来 ping 网站。 最好的方法是使用图像,如果您知道您正在调用的网站有一个 favicon 或某种图标可以抓取,您可以使用 html 图像标签并使用 onerror 事件。

        例子:

        function pingImgOnWebsite(url) {
            var img = document.createElement('img');
            img.style.visibility = 'hidden';
            img.style.position = 'fixed';
            img.src = url;
            img.onerror = continueBtn; // What to do on error function
            document.body.appendChild(img);
        }
        

        【讨论】:

          【解决方案9】:

          另一种方法是使用 PHP。

          你可以添加

          <?php
          if (file_exists('/index.php')) 
          { 
          $url = '/index.php';
          } else {
          $url = '/notindex.php';
          }
          ?>
          

          然后

          <a href="<?php echo $url; ?>Link</a>
          

          【讨论】:

          • 如果 PHP 没有在 OP 的网络服务器上运行怎么办?使用 ASP.NET 生成该页面是完全有效的。
          • 这只是另一种方法。
          • 标题很清楚:how to check... using *JavaScript* - 不是 PHP。不是 ASP.NET - JavaScript。代码可能是正确的,但与这个问题无关..
          • node.js o_O 怎么样,哈哈,我确定这个人正在寻找解决问题的前端方法
          猜你喜欢
          • 2015-02-18
          • 1970-01-01
          • 1970-01-01
          • 2012-03-28
          • 1970-01-01
          • 2010-09-20
          • 2012-03-17
          • 1970-01-01
          • 2011-10-15
          相关资源
          最近更新 更多