2012年8月22日星期三

JS跨域问题解决方法

近日在做web呼叫的时候碰到JS跨域问题,需与华为的服务器交互,用户提交客户号和验证码后,到华为的服务器上去验证用户信息,然后返回用户信息给我们的网页,直接用ajax访问在IE上有安全提示问题,用户信息可返回,调低安全级别可实现,但作为门户网站,让客户去适应我们的要求,这种方法是不可行的,参考了网上一篇“服务器端可控情形JS跨域访问解决方法”,这位老大写了个大概,对我这种低手来说仍然是有点不清不楚的,经过一天痛苦的摸索之后,用动态脚本的方式实现了跨域的解决,现把代码记录下来,以便今后查看。

我启了两个服务,分别是tomcat和weblogic。用tomcat的工程模拟本地,weblogic的工程模拟远程。

先在本地的页面中这样做

java 代码
  1. function transTest(){   
  2.     var username = document.form1.username.value;   
  3.     var email = escape(document.form1.email.value);   
  4.     var url = "http://10.13.78.95:7001/finprog/registerCheckUserByAjax.do?username="+username+"&email="+email;   
  5.     url = encodeURI(url);    
  6.        
  7.     var js_obj = document.createElement( "script" );    
  8.     js_obj.type = "text/javascript";    
  9. js_obj.setAttribute( "src" , url);    
  10. document.body.appendChild(js_obj);   
  11. }   
  12.   
  13. function onServerResponse(responseText){   
  14.     alert(responseText);   
  15.     var message = document.getElementById("message");   
  16.     if(message.hasChildNodes()){   
  17.             message.removeChild(message.childNodes[0]);   
  18.     }   
  19.     var messagenode=document.createTextNode(responseText);//??????   
  20.     message.appendChild(messagenode);   
  21.        
  22. }  

上面jsp页面中,执行transTest()方法后,document.createElement( "script" ); 会动态的在页面中生成一段script脚本,然后在脚本中,绕过IE的安全验证,js_obj.setArrribute() 将信息作为 src 的 url 参数提交给了远程servlet,(用的.do请求,名字是finprog工程里的一个servlet,我懒,不想新写)。

在registerCheckUserByAjax.do中的最末,我返回给建立通信的jsp页面以信息,代码如下:

java 代码
  1. UserInfoDTO userinfoDTO = (UserInfoDTO) serviceModel.get("userinfoDTO");   
  2.         String responseText;   
  3.         if(userinfoDTO==null){   
  4.             responseText="成功";   
  5.         }else if (userinfoDTO.getUserName().equals(username) && userinfoDTO.getEmail().equals(email)) {   
  6.             responseText="失败";   
  7.         } else {   
  8.             responseText="成功";   
  9.         }   
  10.         responseText = new String(responseText.getBytes(), "ISO-8859-1");   
  11.         response.getWriter().println("var a='" + responseText + "';");    
  12.         response.getWriter().println("onServerResponse(a); ");   

这里去调JSP页面中的onServerResponse()方法,回显信息给本地。 这样本地网页就会响应服务器结果,通过message节点把服务器端信息给回显出来,如果是中文要先编好码。

上面的方法我在IE和FireFox中都测过,大功告成。

另外参考网上的解决方法,还可以用本地代理页面,涉及到配置Apache的问题,看得我头昏,我想到了一些解决方法,用一个本地的servlet,在JS提交的时候,提交到本地servlet,然后本地servlet去请求远程servlet,至于怎么建立通信传值,可以这样,在远程servlet中再请求本地的servlet,这时本地servlet对于远程来说,也变成服务器端了,本地再response回给JSP,这是个笨办法。不过没试过。另外,可以用socket方案,不过对于我们公司的层层防火墙是个考验,还有可以在本地存放一个临时页面,用HttpURLConnection con = (HttpURLConnection)url.openConnection();   
与远程建立连接,不过也没试过。暂时没有精力去搞了。

没有评论:

发表评论