9

为什么我对 Web 服务的 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);
    }


    }

所有这些放在一起都有效。

4

0 回答 0