普元EOS中, 子系统和portal不在同一个域中,使用jquery的jsonp来解决portal跨域访问

转至元数据起始


【背景】

子系统和portal不在同一个域中且项目中要求不能使用nginx、apache等反向代理软件,故使用jsonp从代码角度解决ajax跨域问题

【实现思路】

通过jquery的jsonp来实现ajax的跨域访问,具体实现步骤如下:

1, 判断菜单url是否和portal同域。

2, 同域则通过原有方式获取菜单,不同域则通过jsonp方式获取菜单。

3, 修改不同域集成子应用菜单生成代码,满足jsonp格式要求。

【关键代码】

1、修改portal的代码(有一定代码量,不在页面上体现,请参考附件demo):

1)pui-all.js,新增命名空间Pui.datap,用于处理跨域ajax。其中转换json的调用方法JSON.stringify,该方法不支持低版本ie,需导入json2.js(见附件)。

2)修改menuTree.js的createStore方法,该方法用于菜单树的生成,如ajax地址跨域,则走else分支,调用Pui.datap命名空间(此命名空间在pui-all.js定义)。

3)修改menuTreeUIService.jsp,添加<script type="text/javascript" src="<%=contextPath%>/runtime/integration/pui/json2.js"></script>,支持低版本ie转化json。

上述三步完成后,portal端的代码改造就完成了,portal应用通过原方式进行ajax调用,非portal应用通过jsonp方式进行调用,因为jsonp方式需要对服务端返回值格式有特殊要求,故需修改集成子应用生成菜单的代码。

2、修改应用代码:

集成子应用代码以eos(default)应用为例,第三方应用方法相同。

增加jsonp_menu.jsp页面(portal里应用菜单路径为该页面地址),该页面实现了封装菜单变为jsonp格式代码。

<%@page import="javax.servlet.http.HttpServletResponse"%>

<%@page import="org.gocom.components.coframe.auth.login.LoginService"%>

<%@page import="java.util.List"%>

<%@page import="com.primeton.cap.auth.MenuTree.MenuTreeNode"%>

<%@page import="com.primeton.common.util.JsonTransUtil"%>

<%@page import="java.net.URLDecoder"%>

<%@page import="java.io.PrintWriter"%>

<%

String jsonp = request.getParameter("jsonpcallback");

String appCode = request.getParameter("appCode");

LoginService ls = new LoginService();

List<MenuTreeNode> mtn = ls.getUserMenuTreeByAppCode(appCode);

String temp = JsonTransUtil.List2Json(mtn,jsonp);

System.out.println(temp);

response.setContentType("text/xml;charset=utf-8");

response.setHeader("Cache-Control", "no-cache");

PrintWriter po = response.getWriter();

po.write(temp);

po.flush();

po.close();

%>

其中用到了类JsonTransUtil.List2Json

该类实现代码如下,fastjson-1.2.2.jar见附件:

package com.primeton.common.util;

import java.util.List;

import com.alibaba.fastjson.JSON;

import com.eos.system.annotation.Bizlet;

@Bizlet("Json转换工具类")

public class JsonTransUtil{

@Bizlet("List转json")

public static String List2Json(List list,String jsonpcallback){

String json = JSON.toJSONString(list);

json = "{\"treeNodes\":"+json+"}";

json = json.replaceAll("\"","\'");

json = jsonpcallback + "("+json+")";

return json;

}

}

跨域解决方案.zip(代码供参考,因为还包括其他的修改,请不要直接覆盖到项目里)

备注:若portal主题使用多页签模式且没有使用反向代理,只是通过jsonp解决跨越问题,可能会出现session覆盖的问题;

问题场景:weblogic应用服务器,第一个页签中打开A应用a功能,在第二个页签中打开B应用b功能,再切换到第一个页签点击a功能,此时报错。

跟踪分析:通过监控发现,此时点击a功能系统会重新登陆,重新登陆请求是通过a功能发出的,因为a功能发送ajax请求跨域,导致重新登陆失败,功能报错。

查看响应文件发现,应用A和应用B的cookieName 都叫jsessionid,访问应用B的时候生成的jsessionid覆盖了A的jsessionid,再次访问A的时候A 应用的服务端不认识被覆盖后的jsessionid,故判断A应用未登陆,功能出现了问题。

解决办法: 修改weblogic的配置文件weblogic.xml中的cookiename,将每个应用的cookiename修改的不同,故jsessionid不会互相覆盖,不会出现上述问题详细场景:

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值