【问题标题】:How to check if a url is valid (actually loads a page with content) efficiently?如何有效地检查 url 是否有效(实际上是加载带有内容的页面)?
【发布时间】:2020-02-18 17:36:21
【问题描述】:

问题:

如何检查 url 是否有效并实际加载页面?

使用我当前的代码,只检查状态码,这意味着像http://fsd.com/ 这样的网址将被视为有效,尽管它不会加载任何内容。

如何检查 url 是否确实指向可以加载的网站?


代码:

$.ajax({
                    url: link,
                    dataType: 'jsonp', 
                    statusCode: {
                        200: function() {
                            console.log( "status code 200 returned");
                            validURL = true;
                        },
                        404: function() {
                            console.log( "status code 404 returned");
                            validURL = false;
                        }
                    },
                    error:function(){
                        console.log("Error");
                    }
                });

编辑: 有效,我的意思是页面最终被部分加载(至少加载了 html 和 css),而不是永远加载或以某种方式失败而状态代码为 404 .

EDIT2: http://fsd.com 现在实际上返回了一个 404,因为它应该......

EDIT3: 另一个示例:https://dsd.com 加载一个空页面(状态代码 200),而 http://dsd.com 实际上加载一个包含内容的页面(状态代码 200)。在我的 Node.js 后端,npm 包“url-exists”表示 https://dsd.com 无效,而我的前端带有我的问题中显示的代码表示它是一个有效的 url。这是包代码的样子:https://github.com/boblauer/url-exists/blob/master/index.js 但我想知道根据 SO 用户的最佳方式是什么。

EDIT4:

遗憾的是,Addis 提供的请求显然被 CORS 阻止了,这阻止了我的其余代码的执行,而我的原始请求没有。

$.ajax({
                    type: "HEAD",
                    url: link,
                    dataType: 'jsonp', 
                }).done(function(message,text,response){
                    const size = response.getResponseHeader('Content-Length');
                    const status = response.status;
                    console.log("SIZE: "+size);
                    console.log("STATUS: "+status);
                    if(size > 0 && status == "200") {
                        $("#submitErrorMessage").css("display","none");
                        $('#directoryForm').submit();
                    }
                    else {
                        $("#submitErrorMessage").css("display","block");
                        $("#submitLoading").css("display","none");
                    }
                });

编辑 5:

更准确地说,这两个请求都会在浏览器控制台中触发一条警告消息,指示响应已因 CORS 而被阻止,但我的原始代码实际上已全部执行,而另一个请求没有到达控制台.log()。

编辑 6:

$.ajax({
                    async: true,
                    url: link,
                    dataType: 'jsonp', 
                    success: function( data, status, jqxhr ){
                        console.log( "Response data received: ", data );
                        console.log("Response data length: ", data.length);
                        console.log("Response status code: ", status);
                        if (status == "200" && data.length > 0) {
                            $("#submitErrorMessage").css("display","none");
                            $('#directoryForm').submit();
                        }
                        else {
                            $("#submitErrorMessage").css("display","block");
                            $("#submitLoading").css("display","none"); 
                        }

                    },
                    error:function(jqXHR, textStatus, errorThrown){
                        console.log("Error: ", errorThrown);
                    }
                });

错误:

Error:  Error: jQuery34108117853955031047_1582059896271 was not called
    at Function.error (jquery.js:2)
    at e.converters.script json (jquery.js:2)
    at jquery.js:2
    at l (jquery.js:2)
    at HTMLScriptElement.i (jquery.js:2)
    at HTMLScriptElement.dispatch (jquery.js:2)
    at HTMLScriptElement.v.handle (jquery.js:2)

【问题讨论】:

  • 你的意思是一个 URL 是有效的并且实际上可以加载?如果您获得 200,则可以到达并加载它。您能更具体地说明您的需求吗?
  • 由于没有有效页面的真正定义,因此您确实不能。 http code 200 是页面打开成功的唯一指示。
  • @blurfus 编辑了问题。
  • 嗯,我还不清楚。如果您收到 200 状态代码,则该页面可以加载(并且在许多情况下,其数据已经在响应中)。
  • @blurfus 你可能是对的。检查 EDIT2。我想知道为什么它在不加载之前返回 200:/

标签: javascript jquery ajax url status


【解决方案1】:

没有内容的成功响应“应该”返回 204: No Content,但这并不意味着每个开发人员都正确实施了规范。我想这真的取决于您认为“有效”对您的业务案例意味着什么。

Valid = 200 && body 有一些内容吗?

如果是这样,您可以在成功回调中对此进行测试。

$.ajax({
    url: link,
    dataType: 'jsonp',
    success: function (response) {  
        // todo: test the response for "valid"
        // proper length? contains expected content?
    },  
    statusCode: {
        200: function() {
            console.log( "status code 200 returned");
            validURL = true;
        },
        404: function() {
            console.log( "status code 404 returned");
            validURL = false;
        }
    },
    error:function(){
        console.log("Error");
    }
});

【讨论】:

    【解决方案2】:

    我认为“有效”这个词在这里用的有点不对。查看代码 sn-p,我可以看到您正在使用 HTTP 错误代码来确定 URL 是否有效。但是,根据描述,很明显,您认为资源(由 URL 指向)仅当它是网页时才有效。我想强调HTTP 可用于访问不需要web page 表示的资源。

    我认为您需要更深入地从您收到的HTTP 响应中检索该信息(无论它是网页表示形式),并且仅仅依靠状态代码会对您产生误导。一个明确的指标是查看content-type: text/html 的响应标头。

    访问 www.google.com 的响应示例:

    date: Tue, 18 Feb 2020 17:51:12 GMT
    expires: -1
    cache-control: private, max-age=0
    content-type: text/html; charset=UTF-8
    strict-transport-security: max-age=31536000
    content-encoding: br
    server: gws
    content-length: 58083
    x-xss-protection: 0
    

    【讨论】:

      【解决方案3】:

      HEAD 请求用于获取包含在 HTTP 标头中的 meta-information。好消息是响应不包含正文。它非常快,服务器中不应该有任何繁重的处理来处理它。这便于快速检查状态。

      HEAD 方法与 GET 相同,只是服务器不能 在响应中返回消息体。元信息 包含在响应 HEAD 请求的 HTTP 标头中应该是 与响应 GET 请求而发送的信息相同。这 方法可用于获取有关实体的元信息 由请求隐含而不传输实体主体本身。 这种方法通常用于测试超文本链接的有效性, 可访问性和最近的修改。 www.w3.org

      $.ajax({
          type: "HEAD",
          async: true,
          url: link,
          dataType: 'json', 
      }).done(function(message,text,response){
          const size = response.getResponseHeader('Content-Length');
      
          //optionally you may check for the status code to know if the request has been successfully completed
          const status = response.status;
      });
      

      Content-Length 是头部请求中可用的元数据之一,它以字节为单位给出正文的大小,因此通过仅检查大小而不加载整个页面,您可以检查响应中是否有某些内容可用身体。 -

      编辑: 以上代码适用于dataTypejson。对于dataTypejsonpsuccesserror 属性的回调函数将采用如下响应:

      $.ajax({
          url: link,
          dataType: 'jsonp', 
          crossDomain: true,
          data: data,
          success: function( data, status, jqxhr ){
              console.log( "Response data received: ", data );
              console.log("Response data length: ", data.length);
              console.log("Response status code: ", status);
          },
          error:function(jqXHR, textStatus, errorThrown){
              console.log("Error: ", errorThrown);
          }
      }
      

      【讨论】:

      • 由于某种原因,“HEAD”请求似乎因为 CORS 而被阻止,而我的原始请求却没有。
      • 请检查 EDIT4 我的问题。
      • 还添加了EDIT 5。
      • 好的,我正在看。
      • 感谢您的回复。可悲的是,它确实改变了任何东西:/
      【解决方案4】:

      你想要完成的不是很具体,我不会给你一个关于如何做到这一点的代码示例,但这里有一些指针。

      您可以通过不同的方式获得响应:状态代码与您获得的响应无关,您可能有 200 响应但没有数据,或者某些数据出现 500 错误,这可能是一个 html页面显示错误或 json 对象,甚至是指定错误的字符串。

      当您说“实际加载页面”时,我猜您指的是 html 响应,您可以检查响应标头上的 Content-Type 标头并查找 text/html 并检查 Content-Length 标头检查您的响应中是否有内容,即使您检查了这些内容,也很难判断 html 是否实际显示任何内容。

      这真的取决于你具体看什么,我的建议是检查Content-Type 标头和Content-Length,它还取决于网站的实现,因为每个人可能有不同的实现 HTTP 协议的方式。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2010-10-12
        • 2010-12-20
        • 1970-01-01
        • 1970-01-01
        • 2012-08-13
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多