在ColdFusion中表单范围中未定义AJAX请求的发布参数



我正在开发一个ColdFusion 8培训应用程序,在那里我提出了一些AJAX请求(没有任何库,如jQuery),以支持一个非常基本的CRUD应用程序。高级体系结构包括一个CFM视图,一个具有远程访问方法的CFC,用于接收AJAX请求,以及一个充当模型并具有所有数据库查询的CFC。对于只检索不需要任何绑定变量的数据(比如从表中获取所有行),AJAX查询运行良好。然而,当我试图将任何内容发布到CFC中间层时,我会收到关于我在Form范围中查找的未定义值的错误(据我所知,Form范围是post参数的存储位置)。我甚至用TamperData分析了请求,并验证了post参数的名称和值是否如我所期望的那样

以下是JS AJAX请求的示例:

    function addLocation(locToAdd) {
            var thisAccess = new AccessStruct("POST", "jsontest.cfc?method=addNewLocation", getLocations, "newLoc=" + JSON.stringify(locToAdd));
            accessWrapper("addLoc", thisAccess);
    function accessWrapper(action, accessDef) {
            var ajaxRequest = new XMLHttpRequest();
            var nextStep;
            if (action != "getLocs") {
                nextStep = getLocations;
            } else {
                nextStep = buildTable;
            }
            ajaxRequest.onreadystatechange = function() { // using a closure so that the callback can
                if (ajaxRequest.readyState == 4) {        //   examine the request and nextStep
                    if (ajaxRequest.status == 200) {
                        if (nextStep != null) {
                            nextStep(ajaxRequest);
                        }
                        return true;
                    } else {
                        alert("Request Could Not Be Completed; Errors On Page");
                        return false;
                    }
                }
            }
            ajaxRequest.open(accessDef.method, accessDef.url, true);
            ajaxRequest.send("newLoc=" + accessDef.params);
    }

    function Loc(locCode, parLocCode, name, addrL1, addrL2,
                            city, stateProv, postal, locTypeCode) {
            this.locCode     = locCode;
            this.parLocCode  = parLocCode;
            this.name        = name;
            this.addrL1      = addrL1;
            this.addrL2      = addrL2;
            this.city        = city;
            this.stateProv   = stateProv;
            this.postal      = postal;
            this.locTypeCode = locTypeCode;
        }
        function AccessStruct(method, url, nextStep, params) {
            this.method   = method;
            this.url      = url;
            this.nextStep = nextStep;
            this.params   = params;
        }

从本质上讲,页面上发生的事情是为"用户"呈现一个由所有位置(loc)记录填充的表。有一个表单可以添加新用户,当他们单击添加按钮时,会创建一个Loc结构,其中包含他们输入的信息,并将其传递给addLocation函数。这将创建一个Access结构,其中将包括请求URL、方法、用作回调的函数的名称以及任何post参数。这一切都传递到accessWrapper函数中,该函数将创建XMLHttpRequest并处理AJAX请求。我为onreadystatechange回调函数使用了一个闭包,这样它就可以知道XMLHttpRequest对象和Access结构中定义的回调函数(这个回调函数通常用于在添加、删除或编辑记录后刷新视图表)。

这是报告问题的中间层CFC中的cffunction。我不会费心发布DAO CFC,因为它已经在其他地方进行了测试,在这个过程中甚至没有达到(因为它在中间[或控制器]级别失败)

 <cffunction name="addNewLocation" output="false" access="remote">
    <cfset var deserializedLocation = "">
    <cfscript>
        deserializedLocation = DeserializeJSON(Form.newLoc);
    </cfscript> 
    <cfobject component="locationDAO" name="locationDAOObj">
    <cfinvoke
        component="#locationDAOObj#"
        method="addLocation">
        <cfinvokeargument name="code" value="#deserializedLocation.locCode#">
        <cfinvokeargument name="parentCode" value="#deserializedLocation.parLocCode#">
        <cfinvokeargument name="name" value="#deserializedLocation.name#">
        <cfinvokeargument name="addr1" value="#deserializedLocation.addrL1#">
        <cfinvokeargument name="addr2" value="#deserializedLocation.addrL2#">
        <cfinvokeargument name="city" value="#deserializedLocation.city#">
        <cfinvokeargument name="stateProv" value="#deserializedLocation.stateProv#">
        <cfinvokeargument name="postal" value="#deserializedLocation.postal#">
        <cfinvokeargument name="locationType" value="#deserializedLocation.locTypeCode#">
    </cfinvoke>
</cffunction>

请求响应中的错误为:FORM 中未定义500元素NEWLOC

就像我之前说的,我已经在坦帕数据中检查了请求,在那里看起来很好。提前感谢你们这些伟大的人所能提供的任何帮助!

当您向CFC发布Ajax时,绝对存在FORM范围。

此示例通过Ajax将表单数据POST到没有参数的CFC函数,并返回form作用域的JSON格式。是的,您应该有要记录的参数,指定必需/不必需和数据类型,但它们不是强制性的。

你不使用jQuery有什么原因吗?这可能会让你的生活更轻松。

将表单数据发送到Ajax调用的方式一定有问题。如果使用FireBug监视Ajax调用,则可以看到POSTed参数。

HTML

<html>
    <head>
        <title>Ajax POST to CFC</title>
        <script src="//ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
        <script type="text/javascript" src="test.js">
    </head>
    <body>
        <form id="foo" action="" method="post">
            <input type="text" id="a" name="a" value="Hello" />
            <br />
            <input type="text" id="b" name="b" value="Goodbye" />
            <br />
            <textarea id="data" cols="30" rows="10" disabled="true"></textarea>
            <br />
            <input type="button" id="btnSubmit" value="Do Ajax!" />
        </form>
    </body>
</html>

JavaScript

$(document).ready(function() {
    $('#btnSubmit').on('click', function() {
        $.ajax({
            asynch : true,
            type : 'POST',
            dataType : 'json',
            url : 'test.cfc?method=testing&returnformat=json',
            data : {
                a : $('#a').val(),
                b : $('#b').val()
            },
            success : function(data, textStatus) {
                $('#data').val(JSON.stringify(data));
            }
        });
    });
});

CFC

<cfcomponent>
    <cffunction name="testing" access="remote" output="false" returntype="string">
        <cfreturn serializeJSON( form ) />
    </cffunction>> 
</cfcomponent>


老派,没有jQuery,只有普通的'JavaScript

我在这里找到了一个没有jQuery的Ajax POST的简单示例:http://www.openjs.com/articles/ajax_xmlhttp_using_post.php

HTML
删除jQuery SCRIPT标记,将另一个SCRIPT更改为test-noq.js,并更改submit按钮以添加onclick事件。

<input type="button" id="btnSubmit" value="Do Ajax!" onclick="doSubmit();" />

JavaScript:test-nojq.js

function doSubmit(){
    var http = new XMLHttpRequest();
    var url = "test.cfc";
    var params = "method=testing&returnformat=json";
        params += "&a=" + document.getElementById('a').value;
        params += "&b=" + document.getElementById('b').value;
    http.open("POST", url, true);
    //Send the proper header information along with the request
    http.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
    http.setRequestHeader("Content-length", params.length);
    http.setRequestHeader("Connection", "close");
    http.onreadystatechange = function() {//Call a function when the state changes.
        if(http.readyState == 4 && http.status == 200) {
            document.getElementById('data').value = http.responseText;
        }
    }
    http.send(params);
}

newLoc作为一个参数,它应该可以工作。

<cffunction name="addNewLocation" output="false" access="remote">
  <cfargument name="newLoc">
  ...
</cffunction>

更新:不确定为什么一次调用远程方法时没有遇到表单作用域。不管怎样,这不是真的,但答案的其余部分应该仍然成立。

最新更新