使用JavaScript检测URL是否存在,然后再在iframe中显示。

52
我正在使用 JavaScript 将动态 URL 传递给 iframe 的 src。但有时该 URL 不存在,我应该如何事先检测到这种情况,以便在带有 404 错误的 iframe 隐藏它。
8个回答

102
由于我的声望低,我无法对 Derek 朕會功夫的回答进行评论。我已经尝试了那段代码,但它并没有很好地工作。在 Derek 朕會功夫的代码中有三个问题。
  1. 第一个问题是异步发送请求并更改其属性“status”的时间比执行下一个表达式——if(request.status === "404")更慢。因此,由于网络带宽的原因,请求状态将最终保持为0(零),并且它将无法实现if语句下方的代码。要解决这个问题很容易:在ajax请求的打开方法中将'true'更改为'false'。这将导致您的代码短暂地(或不那么)被阻塞(由于同步调用),但会在到达if测试之前更改请求的状态。

  2. 第二个问题是状态是一个整数。使用 '===' javascript 比较运算符时,您正在尝试比较左侧对象是否与右侧对象完全相同。要使此操作正常工作,有两种方法:

    • 删除括号中的引号,使它成为整数;
    • 使用javascript的运算符“==”,这样您就可以测试两个对象是否相似。
  3. 第三个问题是XMLHttpRequest对象仅适用于较新的浏览器(Firefox、Chrome和IE7+)。如果您希望该代码片段在所有浏览器上都能正常工作,您必须按照W3Schools的建议进行操作:w3schools ajax

对我真正有用的代码是:

var request;
if(window.XMLHttpRequest)
    request = new XMLHttpRequest();
else
    request = new ActiveXObject("Microsoft.XMLHTTP");
request.open('GET', 'http://www.mozilla.org', false);
request.send(); // there will be a 'pause' here until the response to come.
// the object request will be actually modified
if (request.status === 404) {
    alert("The page you are trying to reach is not available.");
}

13
因为你的声望较低,所以给你加了一个赞(加一分)。(还有因为你的好回答 :)) - silver
12
不不不,请不要将任何与W3C相关的内容链接到W3 Schools。它们没有任何关联。请注意,我的翻译已经尽可能保持原意并使其更加通俗易懂。 - IE5Master
3
请注意:在主线程上同步使用XMLHttpRequest已被弃用,因为它对最终用户的体验产生了不良影响。欲获得更多帮助,请参阅https://xhr.spec.whatwg.org/。 - Aus
1
点赞让他有足够的声望在 Derek 朕會功夫 的回答下发表评论!(好答案,别让任何事情阻止你兄弟) - KADEM Mohammed
我很惊讶人们真的点赞了这个。请不要使用这个解决方案。同步/"暂停"根本不被视为最佳实践。尝试在浏览器调试中将节流设置为缓慢的3G连接,并注意当"暂停"发生时,用户无法对页面进行任何操作。 即使是其他答案中的Jquery解决方案也采用异步方法更好(即使您不想包含jquery,也可以以此为例)。 - izzulmakin

44

使用XHR并查看是否返回404。

var request = new XMLHttpRequest();  
request.open('GET', 'http://www.mozilla.org', true);
request.onreadystatechange = function(){
    if (request.readyState === 4){
        if (request.status === 404) {  
            alert("Oh no, it does not exist!");
        }  
    }
};
request.send();

但是请注意它只能在相同的源上运行。对于另一个主机,你将不得不使用服务器端语言来完成这个任务,而且你必须自己解决。


1
@Mario - 是的,只要它在相同的源中,由于同源策略的限制。 - Derek 朕會功夫
@Derek朕会功夫 你是怎么给评论添加灰色背景的?#好奇 - GorvGoyl
1
@JerryGoyal 把它用反引号 (`) 包起来 - Derek 朕會功夫
不错的回答 - 但是如果程序员控制着那个资源并且需要允许跨域请求,他们可以自由地这样做;在这种情况下仍然是一个好的答案。 - Gerard ONeill
您还可以使用">= 400"来捕获所有的HTTP错误代码。 - raw-bin hood
拒绝加载chrome-extension://bfnaelmomeimhlpmgjnjophhpkkoljpa/icon16.png。资源必须在web_accessible_resources清单键中列出,以便由扩展程序外的页面加载。 - huykon225

9

我在我的场景中发现这个方法可行。

自 jQuery 1.5 引入的 jqXHR.success()、jqXHR.error() 和 jqXHR.complete() 回调方法已经在 jQuery 1.8 中被弃用。为了准备将来删除它们,应该使用 jqXHR.done()、jqXHR.fail() 和 jqXHR.always()。

$.get("urlToCheck.com").done(function () {
  alert("success");
}).fail(function () {
   alert("failed.");
});

7
我创建了这个方法,它非常理想,因为它可以在未完全下载文件的情况下中止连接,非常适合检查视频或大型图像是否存在,减少响应时间和需要下载整个文件的需求。
// if-url-exist.js v1
function ifUrlExist(url, callback) {
    let request = new XMLHttpRequest;
    request.open('GET', url, true);
    request.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset=UTF-8');
    request.setRequestHeader('Accept', '*/*');
    request.onprogress = function(event) {
        let status = event.target.status;
        let statusFirstNumber = (status).toString()[0];
        switch (statusFirstNumber) {
            case '2':
                request.abort();
                return callback(true);
            default:
                request.abort();
                return callback(false);
        };
    };
    request.send('');
};

使用示例:

ifUrlExist(url, function(exists) {
    console.log(exists);
});

2

如果URL在同一域中,您可以通过AJAX测试该URL并读取状态码。

如果它是远程域,您可以在自己的域上使用服务器脚本检查远程URL。具体操作请参考此链接


1
使用async/await,我成功地打开了一个新的标签页;出于和 OP 相同的原因,我需要检测 404 错误:
openHelp : async function(iPossiblyBogusURL) {
    const defaultURL = `http://guaranteedToWork.xyz`;
    const response = await fetch(iPossiblyBogusURL);

    if (response.status == 200) {
        window.open(iPossiblyBogusURL, `_blank`);
    } else if (response.status === 404) {
        window.open(defaultURL, `_blank`);   
    }
},

0

无需单独进行HTTP请求以提前检查。

您可以切换逻辑:仅当iframe成功加载后才显示。为此,可以将一个onload事件监听器附加到iframe上。

有关详细信息,请参见相关问题: 捕获iframe加载完成事件


0

您可以尝试在页面上执行简单的GET操作,如果返回200,则表示该页面存在。使用jQuery尝试此操作,函数是成功页面加载的回调函数。请注意,为了防止XSS,此方法仅适用于您域内的站点。其他域必须在服务器端处理。

$.get(
   yourURL,
   function(data, textStatus, jqXHR) {
      //load the iframe here...
   }
);

这个问题没有被标记为“jquery”,我认为来到这里的人不是在寻找使用这个库的解决方案。 - gouessej

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接