nodejs request模块请求一个无效网址,但返回正确的问题

最近做一个服务转发功能,但是对端服务可能没有开启或已经宕机,因此在转发前需要判断此次转发的服务是否是有效的(或者转发后能分辨此次响应是否正常),如果是不存在的服务下次转发需要屏蔽掉。

封装了一个request方法:

const request = require('request');

async function GetResponse(url) {
    return new Promise((resolve, reject) => {
        request({
            url: url,
            method: "GET",
            encoding: null, // setting null can avoid some encoding trouble
            headers: {
              //'Accept-Encoding': 'gzip, deflate'
            }
          }, function (error, response, body) {
            if (body){
                resolve(response);
            } else if (error){
                reject(error);
            }
          });
        //   .on('socket', function (sok){
        //       console.log(sok);
        //       sok.on('data', function (fin){
        //           console.log(fin);
        //       });
        //   });
    });
}

此方法使用了promise方式,可达到等待的目的,如果请求还未返回则进行阻塞,直到请求url有响应了(即使是error)才会继续后面的逻辑。调用时需要在一个async方法中调用:

 let result = await GetResponse("http://www.baidu.com");

如果请求成功,则callback中的error为null,body内容为响应体(和response['body']一致,因此建议返回response对象,自行获取响应体,期间还可以判断响应状态等信息);

如果请求失败,callback中的error则为错误对象,message中可以获取具体错误信息。

================================================================================================

问题:最近测试时,使用了两个域名,一个http://www.baidu.com,一个自己编的并且用浏览器访问确实是不存在的,却发现错误的域名竟然也能正确返回,并且状态码也是200,statusMessage也是OK。

先了解一下一次http请求的基本流程:

  1. 根据域名和 DNS 解析到服务器的IP地址 (DNS + CDN)
  2. 通过ARP协议获得IP地址对应的物理机器的MAC地址
  3. 浏览器对服务器发起 TCP 3 次握手
  4. 建立 TCP 连接后发起 HTTP 请求报文
  5. 服务器响应 HTTP 请求,将响应报文返回给浏览器
  6. 短连接情况下,请求结束则通过 TCP 四次挥手关闭连接,长连接在没有访问服务器的若干时间后,进行连接的关闭
  7. 浏览器得到响应信息中的 HTML 代码, 并请求 HTML 代码中的资源(如js、css、图片等)
  8. 浏览器对页面进行渲染并呈现给用户

问题出在第一步域名解析上,不同地区的运营商会有一层代理,去做DNS解析,如果解析不成功,则会返回一个解析失败的空白页,此页面就是response中的body,以天津为例:我使用上述方法请求http://www.nickDaDa.com,callback中error是null,而且获取到了body是一个byte数组。我们在转发router中使用另一种方法转发:

req.pipe(request({ url: 'http://www.nickDaDa.com' })).pipe(res); //request is external package, req&res is router param

使用postman做测试,就会发现,它返回的是一个页面:

<html>
    <script language=javascript type="text/javascript">
    window.location.replace("http://tjdnserror2.wo.com.cn:8080?HOST=" 
        + location.hostname + "&R="
        + location.pathname + "&" + location.search.substr(location.search.indexOf("\?")+1));
</script>
    <noscript>
        <meta   http-equiv="refresh"   content="0;URL=http://tjdnserror2.wo.com.cn:8080">
    </noscript>
    <head>
        <title>Redirect</title>
    </head>
    <body bgcolor="white" text="black"></body>
</html>

因此,转发时只能是用IP:PORT的方式进行测试(也可以先使用DNS自己解析域名,获取到对应IP),这样就能跳过DNS解析这一步,如果服务不可达,则直接返回error对象,进行错误处理即可。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Node.js的request模块一个简单而强大的HTTP客户端,可以用来向HTTP服务器发起请求,并获取服务器的响应。它是一个Node.js内置的模块,以npm包的形式提供。通过使用request模块,你可以方便地实现各种HTTP请求,如GET、POST、DELETE等等。你可以使用request模块来获取网页内容,或者向API接口发起请求,并处理响应。在使用request模块时,你可以通过引入模块并调用相应的方法来发起请求,如使用get方法发起GET请求的示例代码如下: ```javascript var request = require('request'); request('您的请求url', function (error, response, body) { if (!error && response.statusCode == 200) { console.log(body) // 请求成功的处理逻辑 } }); ``` 以上代码中,您需要将"您的请求url"替换为您实际要请求的URL地址。当请求成功时,可以在回调函数中处理响应的内容。 #### 引用[.reference_title] - *1* *3* [nodejs request模块](https://blog.csdn.net/inthat/article/details/114686305)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^koosearch_v1,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* [requestnodejs的内置模块吗](https://blog.csdn.net/weixin_35757531/article/details/129072312)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^koosearch_v1,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值