分布式系统跨域调用问题

     在分布式系统中, 大部分在后台做远程调用, 从hession,到dubbo、dubbox , spring cloud 等,所以前台感觉不到跨域问题, 但是有些特殊要求,需要做前端远程调用

从A系统调用B系统页面,在这里不考虑权限问题 ,因为某些系统单点、授权等方式。

调用方式:

 1、ajax ,

   大部分人用jquery 做为基础框架,那么以jquery 为基础。

直接使用ajax 是不允许跨域 ,报错调用端不允许,那么怎么解决?

首先在调用ajax 增加头部,如下

$.ajax({
             url: href,
             type: "GET",
             dataType:"html",
             beforeSend: function (xhr) {
                 xhr.setRequestHeader("content-type", "web");
                xhr.setRequestHeader("Access-Control-Allow-Origin", "*");
             },
             success: function(data,status){
                 //On ajax success do this
                 console.info("load page "+href+" is success.");
                 renderTable(data);
             },
             error: function(xhr, ajaxOptions, thrownError) {
                 //On error do this
                 console.info("error."+ajaxOptions+",status:"+xhr.status+","+thrownError);
                
             }
           });

这样是允许了调用界面能发出ajax请求,那接收端也要增加对应的回应。

一般如果某个系统需要支持跨域 ,只要增加一个过滤器配置即可,过滤器内容如下

写道
import java.io.IOException;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class CrossDomainFilter implements Filter {

@Override
public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain filterChain) throws IOException, ServletException {
// 强制类型转换
HttpServletRequest request = (HttpServletRequest) arg0;
HttpServletResponse response = (HttpServletResponse) arg1;
request.setCharacterEncoding("UTF-8");
response.setCharacterEncoding("UTF-8");
/*
解决引用出现跨域问题
glyphicons-halflings-regular.woff
glyphicons-halflings-regular.ttf
*/
//跨域设置-start
final String origin = request.getHeader("origin");
if (origin!=null && origin.trim().length()>0) {
response.setHeader("Access-Control-Allow-Origin", origin);
} else {
response.setHeader("Access-Control-Allow-Origin", "*");
}
response.setHeader("Access-Control-Allow-Credentials", "true");
response.setHeader("Access-Control-Allow-Methods", "OPTIONS,GET,PUT,POST,DELETE,HEAD");
response.setHeader("Access-Control-Max-Age", "2592000");
response.setHeader("Access-Control-Allow-Headers","content-type,access-control-allow-origin,access-control-request-headers,access-control-request-method,accept,origin,authorization,x-requested-with,serviceName,locale");
//跨域设置-end

//放行、将请求转发到目的地
filterChain.doFilter(request, response);
}

@Override
public void init(FilterConfig arg0) throws ServletException {
// TODO Auto-generated method stub
}
@Override
public void destroy() {
// TODO Auto-generated method stub
}
}

然后在, web.xml 中增加过滤配置

<!-- 支持跨域 -->
    <filter>
  <filter-name>crossDomainFilter</filter-name>
  <filter-class>org.smartsoft.core.servlet.CrossDomainFilter</filter-class>
 </filter>
 <filter-mapping>
  <filter-name>crossDomainFilter</filter-name>
  <url-pattern>/*</url-pattern>
 </filter-mapping>

  好了,这样就可以A 系统界面访问B系统了。

 提示,如果调用的B系统没有支持跨域 ,那么这种方式失效!

 2、窗体

 无论使用IFrame还是使用 href + target ="_blank" 弹新界面方式,都可以直接调用B界面内容就行了。

所以这是一种很安全的方式,很多插件跨域方式就是使用隐藏的iframe 加载B界面,再用javascript 回写出来。

 3、script 方式

  网传最著名的 ajax 使用jsonp 方式,就是使用script 方式,原理是动态将要加载界面连接在A界面上写个script 标签,连接为javascript 内容,然后等加script 加载完后,再调用。这种方式适合B界面是纯javascrpt 或json 数据。如果是界面html ,xml 就不适用。

以上是目前用得最多的前端跨域 调用。新的html5 如果是仅仅A,B界面通信 ,那使用postmessage 方式即可。

相关推荐