为什么我的jquery AJAX调用Web服务没有返回任何数据?当我打电话给我的网络服务时为什么没有发生?为什么我的Web服务客户端不能在不同的服务器/域上使用Web服务?
我花了相当多的时间研究如何让我的jquery UI应用程序在另一个域上使用Web服务。我终于弄清楚了,并且正在为今后遇到这一挑战的任何人记录细节。注意,我正在对JBOSS v4容器中托管的一组Documentum DFS POJO Web服务使用jquery $ .ajax调用。较新版本的Tomcat / JBOSS使这更容易。
这是等式的jquery方面:
<script type="text/javascript">
var tjson;
var webServiceURL = 'http://hostname/services/pDFS/atlContractService';
var soapMessage;
$(document).ready(function() {
jQuery.support.cors = true;
});
function onSaveTitleData() {
soapMessage = '<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ser="http://service.prodagio.com"><soapenv:Header/><soapenv:Body><ser:saveProjectData><prjInfo>' + tjson + '</prjInfo></ser:saveProjectData></soapenv:Body></soapenv:Envelope>';
CallService();
}
function CallService()
{
$.ajax({
url: webServiceURL,
type: "POST",
dataType: "xml",
data: soapMessage,
processData: false,
contentType: "text/xml; charset=\"utf-8\"",
success: OnSuccess,
error: OnError
});
return false;
}
function OnSuccess(data, status)
{
alert(data.d);
}
function OnError(request, status, error)
{
alert(request + status + error);
}
function prepareTitleSavePackage(obj, rowIndx) {
var rObjectId = obj.dataModel.data[rowIndx].r_object_id;
var parentId = obj.dataModel.data[rowIndx].parentId;
var contractChronId = obj.dataModel.data[rowIndx].contractChronId;
var picture = obj.dataModel.data[rowIndx].picture;
var project = obj.dataModel.data[rowIndx].project;
var bu = obj.dataModel.data[rowIndx].bu;
var aka = obj.dataModel.data[rowIndx].aka;
var status = obj.dataModel.data[rowIndx].document_status;
if ( !rObjectId || rObjectId.length < 16 ) {
rObjectId = "new";
}
tjson = "{rObjectId : '" + rObjectId + "', picture : '" + picture + "', project: '"
+ project + "', bu : '" + bu + "', aka: '" + aka + "', status : '"
+ status + "', parentId : '"
+ parentId + "', contractChronId : '" + contractChronId + "'}";
//alert(tjson);
}
function addTitleRow() {
var parentId = jQuery("#contractObjId").val();
var contractChronId = parentId;
jQuery("#grid_array").pqGrid( "addRow",
{rowData : { 'parentId' : parentId, 'contractChronId' : contractChronId } }
);
//jQuery("#currentTitleIndex").val(titleRowIndex);
}
</script>
被调用的实际Web服务是一个微不足道的问题。更重要的是,为了避免在调用该服务时(当它托管在不同的域中时)网络安全性错误,您必须实现过滤器。当然,这需要修改应用程序的web.xml并实现过滤器类。
以下是我添加到web.xml的行:
<filter>
<filter-name>pCorsFilter</filter-name>
<filter-class>com.p.dfs.util.CrossOriginRequestSharingFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>pCorsFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
这是实际的Java类实现:
import java.io.IOException;
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;
import javax.servlet.Filter;
import com.documentum.fc.common.DfLogger;
public class CrossOriginRequestSharingFilter implements Filter
{
public void destroy() {
}
public static String VALID_METHODS = "DELETE, HEAD, GET, OPTIONS, POST, PUT";
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
HttpServletRequest httpReq = (HttpServletRequest) req;
HttpServletResponse httpResp = (HttpServletResponse) resp;
try {
// No Origin header present means this is not a cross-domain request
String origin = httpReq.getHeader("Origin");
DfLogger.debug(this.getClass(),"doFilter(): origin " + origin, null, null);
if (origin == null) {
DfLogger.debug(this.getClass(),"doFilter(): origin == null ", null, null);
// Return standard response if OPTIONS request w/o Origin header
if ("OPTIONS".equalsIgnoreCase(httpReq.getMethod())) {
httpResp.setHeader("Allow", VALID_METHODS);
httpResp.setStatus(200);
return;
}
} else {
DfLogger.debug(this.getClass(),"doFilter(): origin != null ", null, null);
// This is a cross-domain request, add headers allowing access
String validOrigins = ReadProperties.getInstance().getString("VALID_ORIGINS");
DfLogger.debug(this.getClass(),"doFilter(): validOrigins " + validOrigins, null, null);
if ( validOrigins.indexOf(origin) > -1 ) {
httpResp.setHeader("Access-Control-Allow-Origin", origin);
httpResp.setHeader("Access-Control-Allow-Methods", VALID_METHODS);
DfLogger.debug(this.getClass(),"doFilter(): header set", null, null);
String headers = httpReq.getHeader("Access-Control-Request-Headers");
if (headers != null)
httpResp.setHeader("Access-Control-Allow-Headers", headers);
// Allow caching cross-domain permission
httpResp.setHeader("Access-Control-Max-Age", "3600");
}
}
DfLogger.debug(this.getClass(),"doFilter(): if origin complete", null, null);
// Pass request down the chain, except for OPTIONS
if (!"OPTIONS".equalsIgnoreCase(httpReq.getMethod())) {
DfLogger.debug(this.getClass(),"doFilter(): chain.doFilter", null, null);
chain.doFilter(req, resp);
}
} catch ( Exception eee ) {
DfLogger.error(this.getClass(),"doFilter(): error " + eee.getMessage(), null, null);
}
}
public void init(FilterConfig config) throws ServletException {
DfLogger.error(this.getClass(),"doFilter(): CrossOriginRequestSharingFilter initialized", null, null);
}
}
所有这些都有效。