nodejs发送http请求时遇到404长时间未响应的解决方法

通常,我们在使用nodejs发送http请求时,一旦遇到404响应,nodejs内部会一直请求下去,直到超出它自己设定的响应时长(最让人恶心的地方就是这个时长还是没法修改的。)很多人在这里碰到了麻烦。

我是在做arcgis地图项目的时候,客户提出需要使用天地图提供的底图服务,当时我直接使用silverlight客户端的Arcgis API进行http请求(同样是内部请求,不开源的东西就是这么让人郁闷),同样碰到了一个进度条一直卡在那的问题。经过调试发现,是由于底图加载请求超时的缘故,和nodejs一样,silverlight一直在进行请求直到超出它自己设定的响应时限。

于是,我当时正好有业余接触nodejs,觉得这个东西性能应该是不错的,至少比tomcat+java之流要好一些。于是,我着手写了一个nodejs的代理服务,用来请求天地图的底图。我当时以为nodejs碰到404时能直接结束请求,但是呢,这个问题好像是行业规范似的,它竟然也和silverlight一样不断的请求……索性上网查了会资料,得出了以下这两段代码,解决了这个一直请求404的问题。

function proxyTDTMapData(img,level,row,col){
  var that = this,request = null,param = img.replace('_w','');
  var filename = tdtimgDir+'/'+img+'_'+level+'_'+row+'_'+col+'.png';
  path.exists(filename, function(exists) {
    if (exists) {
      readFileEntry(filename,that.res);
    }else{
      var url = "http://t0.tianditu.com/"+img+"/wmts?service=wmts&request=GetTile&version=1.0.0&LAYER=" + param + "&tileMatrixSet=w&TileRow=" + row + "&TileCol=" + col + "&TileMatrix=" + level + "&style=default&format=tiles"; 

      httpGetWithTimeoutSupport(url,4000,function(response){
        //console.log("have a response!");
        if(200 == response.statusCode){
          var size = 0;
          var chunks = [];
          response.on('data', function(chunk){
            size += chunk.length;
            chunks.push(chunk);
          });
          response.on('end', function(){
            var data = Buffer.concat(chunks, size);
            that.res.writeHead(200, {
              'Content-Type' : 'image/png',
              'Content-Length' : data.length,
              'Accept-Ranges' : 'bytes',
              'Server' : 'Microsoft-IIS/7.5',
              'X-Powered-By' : 'ASP.NET'
            });
            that.res.write(data, "binary");
            that.res.end();
            fs.writeFile(tdtimgDir+'/'+img+'_'+level+'_'+row+'_'+col+'.png', data);
           });
        }else{
          readFileEntry(mapDir+"/null.png",that.res);
        }
      }).on("error",function(){
        readFileEntry(mapDir+"/null.png",that.res);
      });
    }
  }); 

 } 
function httpGetWithTimeoutSupport(options, timeout, callback) {
  var timeoutEvent; 

  var req = http.get(options, function(res) {
    res.on("end", function() {
      clearTimeout(timeoutEvent);
      // console.log("end");
    })
    res.on("close", function(e) {
      clearTimeout(timeoutEvent);
      // console.log("close");
    }) 

    res.on("abort", function() {
      // console.log("abort");
    }); 

    res.on("error",function(){
      try{
        res.destory();
        clearTimeout(timeoutEvent);
        //console.log("res error catch");
      }catch(e){ 

      }
    });
    callback(res);
  }); 

  req.on("timeout", function() {
    //console.log("request emit timeout received");
    try{
      if (req.res) {
        req.res.emit("abort");
      }
      clearTimeout(timeoutEvent);
      req.abort();
    }catch(e){
      //console.log("req timeout failed!");
    }
  });
  req.on("error",function(){
    try{
      //console.log("req error catch");
    }catch(e){ 

    }
  });
  timeoutEvent = setTimeout(function() {
    try{
      req.emit("timeout");
    }catch(e){
      //console.log("timeout failed!");
    }
  }, timeout); 

  return req;
} 

其原理就是利用nodejs请求的几个事件与计时器,一旦超出设定的响应时长则立马终结请求。如此,进度条一直卡着的问题解决了。
细心的读者可能看到了

path.exists(filename, function(exists) {
    if (exists) {
      readFileEntry(filename,that.res);
    }else{...});

这段代码,其实这里做了一下服务端的图片缓存,一旦加载过的底图图片,直接从本地读取,极大的加快了地图的访问速度(这个在效率上提升了至少10倍)。
至于Arcgis API for Silverlight 是如何实现天地图底图以及其它底图服务(比如非标准墨卡托的地方坐标系底图服务)加载的呢?请听我下回分解。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • NodeJS Express框架中处理404页面一个方式

    在用 Express 的时候,路由是我最困惑的事之一.知道用 app.get('*') 可以处理所有页面,但这样除了自定义的其他路由外,静态文件是被忽略的.最近在写一个小工具的时候,找到了一个解决方案: 复制代码 代码如下: var express = require('express'),    router = require('./routes'); var app = module.exports = express.createServer(); // Configurationapp

  • 使用nodejs中httpProxy代理时候出现404异常的解决方法

    在公司中使用nodejs构建代理服务器实现前后台分离,代码不能拿出来,然后出现httpProxy代理资源的时候老是出现404.明明被代理的接口是存在的.代码大概如下: var http = require('http'), httpProxy = require('http-proxy'); var proxy = httpProxy.createProxyServer({}); var server = http.createServer(function(req, res) { proxy.

  • nodejs发送http请求时遇到404长时间未响应的解决方法

    通常,我们在使用nodejs发送http请求时,一旦遇到404响应,nodejs内部会一直请求下去,直到超出它自己设定的响应时长(最让人恶心的地方就是这个时长还是没法修改的.)很多人在这里碰到了麻烦. 我是在做arcgis地图项目的时候,客户提出需要使用天地图提供的底图服务,当时我直接使用silverlight客户端的Arcgis API进行http请求(同样是内部请求,不开源的东西就是这么让人郁闷),同样碰到了一个进度条一直卡在那的问题.经过调试发现,是由于底图加载请求超时的缘故,和nodej

  • Nodejs 发送Post请求功能(发短信验证码例子)

    直接上代码 sms.js var http = require('http'); var querystring = require('querystring'); function SmsCode() { //发短信 this.send = function (req0, res0) { var code = "3212"; var txt = "您的验证码是:"+code+".请不要把验证码泄露给其他人.如非本人操作,可不用理会!"; var

  • 详解使用fetch发送post请求时的参数处理

    详解使用fetch发送post请求时的参数处理 不考虑古董浏览器之后,使用fetch来发送ajax请求,变得非常爽快和时尚. 但是,发送post请求的时候,把笔者卡了一下.后台如下获取参数时,总是为null String q = req.getParameter("q"); 研究了好久,总算写出正确的使用方式了.直接上代码. fetch("/search/project/", { method: "POST", headers: { 'Conte

  • JQuery发送ajax请求时中文乱码问题解决

    这篇文章主要介绍了JQuery发送ajax请求时中文乱码问题解决,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 先排除项目故障: 1.web.xml中是否配置了字符拦截器 <filter> <filter-name>encodingFilter</filter-name> <filter-class>org.springframework.web.filter.CharacterEncodingFilter

  • 解决PHP使用CURL发送GET请求时传递参数的问题

    最近在使用curl发送get请求的时候发现传递参数一直没有生效,也没有返回值,以为是自己哪里写错了,网上找东西时也没有人专门来说get请求传递参数的内容,所以,今天在这里记录一下,希望可以帮到一些人 get请求是最简单的请求,不过要注意自己的请求是http请求还是https的请求,因为https请求时要关闭SSL验证,不然验证通不过,没有办法请求到数据: GET请求的参数 get传递参数和正常请求url传递参数的方式一样 function get_info($card){ $url ="http

  • 解决node.js含有%百分号时发送get请求时浏览器地址自动编码的问题

    node.js含有%百分号时,发送get请求时浏览器地址自动编码的问题 sales\报表.png 在发到后台时,会自动编码成: /file/view/sales/%E6%8A%A5%E8%A1%A8.png 在node.js会自动反编码成: sales\报表.png 不过如果文件名中含有%百分号,编码过程则会出现问题,如 sales\报%表.png 发送到node.js接收到的自动编码数据: /file/view/sales/%E6%8A%A5%%E8%A1%A8.png %E6%8A%A5%%

  • 解决Python发送Http请求时,中文乱码的问题

    解决方法: 先encode再quote. 原理: msg.encode('utf-8')是解决中文乱码问题. quote():假如URL的 name 或者 value 值中有『&』.『%』或者『=』等符号,就会有问题.所以URL中的参数字符串也需要把『&=』等符号进行编码,quote()就是对参数字符串中的『&=%』等符号进行编码. 例子: # -*- coding: UTF-8 -*- # python2.7 from urllib import quote import req

  • C语言实现最长递增子序列问题的解决方法

    本文实例展示了C语言实现最长递增子序列问题的解决方法.分享给大家供大家参考.具体方法如下: 问题描述: 给定一个序列,找出其最长递增子序列长度. 比如 输入 1 3 7 5 输出 3 算法解决思路: 利用动态规划的思想,以序列的每个点最为最右端,找出每个点作为最右端时的子序列长度的最大值,即问题的求解.因此,在计算前面的每个点的时候,将其结果保存下来,后面的点与前面的点的数值进行比较,如果大,则在其长度基础上加1,并且找出所有可能情况下最长的保存为当前点的长度.形成递归. 具体实现代码如下: #

  • Vue中消息横向滚动时setInterval清不掉的问题及解决方法

    最近在做项目时,需要进行两个组件联动,一个轮询获取到消息,然后将其传递给另外一个组件进行横向滚动展示,结果滚动的速度越来越快.这里记录一下来提醒自己.消息滚动的代码在最下面,方便下次使用. 问题背景: 最近在做一个需求,组件A获取消息采用的是轮询,组件A获取到新的消息后,将组件A中的消息传递给另外一个组件B,当组件B接收到消息时就让消息在页面上滚动播放. 实现思路: 这个项目应用的框架为VUE,当组件A获取到新的消息之后,就触发中央事件总线,在组件B中进行事件监听,将其添加进入一个数组,当判断定

  • Android Studio使用Kotlin时,修改代码后运行不生效的解决方法

    问题现象 前段时间升级 Android Studio 3.1.3+ 版本后,决定尝试使用 Kotlin 做 APP 开发看看.结果却发现,修改 String 资源后,"运行",修改的内容没有生效.一开始以为只是 String 资源是这样,于是试了下 kt 文件,结果发现"运行"也不能生效. 但是先 clean 了,再"运行",却可以正常编译出来.查了好久发现是 New Module 后,Run/Debug Configurations不完整所致.

随机推荐