通过web代理进行跨域访问,http请求返回超时的问题定位

【现象】

在ajax通过web代理跨域访问时,http第一次登陆时正常,但是第二次再下发其他命令的时候总是返回 java.net.SocketTimeoutException: Read timed out

【定位思路】

  第一次登陆正常,第二次再访问就不行,说明大多数是和cookie相关。页面在登陆的时候设置cookie是成功的,那么大部分的原因应该是在web代理部分cookie的传输有问题了。仔细看了代理部分的代码,发现web代理部分建立新的http请求的时候,并没有添加cookie。然后上网查找cookie的获得和添加方式。添加上就可以了。

【前台页面代码】

登陆代码:

function DoLogin()                            
{ 
  m_szUserPwdValue = Base64.encode("admin" + ":" + "12345");
  $.ajax({
      type: "GET",
      url: m_lHttp + m_szHostName + ":" + m_lHttpPort + "/onlineObservationSystem/PSIA/Custom/SelfExt/userCheck",
      async: true,
      timeout: 15000,
      beforeSend: function(xhr) {
          xhr.setRequestHeader("If-Modified-Since", "0");
          xhr.setRequestHeader("Authorization", "Basic " + m_szUserPwdValue);
      },
      success: function(xmlDoc, textStatus, xhr) 
      {
        alert("login success");
          if("200" == xhr.status)
          {
              var szUrl = decodeURI(document.URL);
              if(szUrl.indexOf("?page=") != -1)
              {
                  var szPage = szUrl.substring(szUrl.indexOf("page=") + 5, szUrl.indexOf("&params="));
                  if(szPage.indexOf(".asp") == -1)
                  {
                      szPage = szPage.concat(".asp");
                  }
                  var szParam = szUrl.substring(szUrl.indexOf("&params=") + 8, szUrl.length);
                  $.cookie('page',szPage+"?"+szParam+"%1");
              }
              else
              {
                  $.cookie('page',null);
              }
              //登陆的时候在这里添加cookie
              $.cookie('userInfo'+'80',m_szUserPwdValue==""?Base64.encode("anonymous:177177177177177177"):m_szUserPwdValue);
              //window.location.href = "IEfile/doc/page/main.asp";
          }
          else
          {   
              if(!$('#UserName').prop("disabled")) {
                  $('#UserName').focus();
              }
              $('#UserName').val('');
              $('#Password').val('');
              alert(translator.translateNode(g_lxdLogin, 'LoginTips4'));
          }
      },
      error: function(xhr, textStatus, errorThrown)
      {
        alert("login error = " + textStatus);
          if("timeout" == textStatus)
          {
              alert(translator.translateNode(g_lxdLogin, 'ConnectTimeoutTips'));
          }
          else
          {
              alert(translator.translateNode(g_lxdLogin, 'NetworkErrorTips'));
          }
      }
  });
}  

第二次访问的代码:

    
function GetPatrolsCab() {
    $.ajax({
        type: "GET",
        url: m_lHttp + m_szHostName + ":" + m_lHttpPort + "/onlineObservationSystem/PSIA/PTZ/channels/1/patrols",
        async: true,
        timeout: 15000,
        beforeSend: function(xhr) {
            xhr.setRequestHeader("If-Modified-Since", "0");
            xhr.setRequestHeader("Authorization", "Basic " + m_szUserPwdValue);
        },
        success: function(xmlDoc, textStatus, xhr) {
            var iLen = $(xmlDoc).find('PTZPatrol').length;
            if(0 == iLen) {
                alert("get path success,but iLen=0");
                //m_oPtzTabs.hideTab(1);
                return;
            }
            $("#selectPatrol").empty();
            var szName = parent.translator.translateNode(g_lxdPreview, 'laTrack');
            for(var i = 0; i < iLen; i++) {
                if (i < 9) {
                    $("<option value='"+ (i+1) +"'>"+szName+" 0"+(i+1)+"</option>").appendTo("#selectPatrol");
                } else {
                    $("<option value='"+ (i+1) +"'>"+szName+" "+(i+1)+"</option>").appendTo("#selectPatrol");
                }
            }
            $("#selectPatrol").unbind().bind("change",function() {
                GetPatrol(this.value);
            });
            GetPatrolsDelayCab();
        },
        error: function(XMLHttpRequest, textStatus, errorThrown) {
            alert("get path error");
            //m_oPtzTabs.hideTab(1);
        }
    });
}


【web代理代码,就是servlet端代码】

package com.boomdts.weather_monitor.servlet.video;

import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.charset.Charset;
import java.util.List;

import javax.servlet.*;
import javax.servlet.http.*;

public class psiaFilter implements javax.servlet.Filter {

        public void destroy() {
        }
        //char数组转换成byte数组
        private byte[] getBytes (char[] chars) {
           Charset cs = Charset.forName ("UTF-8");
           CharBuffer cb = CharBuffer.allocate (chars.length);
           cb.put (chars);
           cb.flip ();
           ByteBuffer bb = cs.encode (cb);
           return bb.array();
        }
        //byte数组转换成char数组
        private char[] getChars (byte[] bytes) {
            Charset cs = Charset.forName ("UTF-8");
            ByteBuffer bb = ByteBuffer.allocate (bytes.length);
            bb.put (bytes);
            bb.flip ();
            CharBuffer cb = cs.decode (bb);
            System.out.println("in size=" + bytes.length + "out size = " + cb.array().length);
            return cb.array();
        }

        public void doFilter(ServletRequest request, ServletResponse response,
                FilterChain chain) throws IOException, ServletException {

            //根据当前请求内容获得请求的各个参数
            HttpServletRequest req = (HttpServletRequest)(request);
            String uri = req.getRequestURI();
            uri = uri.substring(24);//删除当前项目名称的字符串
            String Auth = req.getHeader("Authorization");
            String method = req.getMethod();
            Cookie[] cookies = req.getCookies();//取得cookie,这个原来是没有添加的

            HttpServletResponse res = (HttpServletResponse)(response);

            //发起一个新的http连接,设置新建连接的参数(就是把刚才请求的参数设置成新的连接的参数)。
            String url= "http://172.16.8.178" + uri;
            //System.out.println("url = " + url);
            URL theURL = new URL(url);
            HttpURLConnection urlConnection = (HttpURLConnection)theURL.openConnection();

            urlConnection.setReadTimeout(500000);
            System.out.println("method = " + method);
            urlConnection.setRequestMethod(method);
            urlConnection.setRequestProperty("If-Modified-Since", "0");
            urlConnection.setRequestProperty("Authorization", Auth);
            for(Cookie c:cookies){
                urlConnection.addRequestProperty("Cookie",  c.getName() + "=" + c.getValue());//添加cookie,这个原来是没有添加的
                //System.out.println("cookie  name=" + c.getName() +"; value=" + c.getValue());
            }
            urlConnection.connect();
            
            
            PrintWriter out = res.getWriter();
            //取得http连接响应数据,并把响应数据返回前台页面
            if (urlConnection.getResponseCode() == 200)
            {
                System.out.println("urlConnection return success");
                //解析返回信息
                InputStream in = urlConnection.getInputStream();

                int c;
                while((c = in.read()) != -1)
                    out.write(c);
                 
            } else {
                System.out.println("error! urlConnection.getResponseCode() = " + urlConnection.getResponseCode());
            }

        }

        public void init(FilterConfig arg0) throws ServletException {
        }

    }

相关内容请参考我的另外两篇博客:

ajax跨域访问的解决方案

jquery.cookie.js使用介绍

原文地址:https://www.cnblogs.com/matthew-2013/p/3512132.html