简体   繁体   English

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

[英]Post parameters from AJAX request undefined in form scope in ColdFusion

I am working on a ColdFusion 8 training application where I'm making some AJAX requests (without any libraries such as jQuery) to support a very basic CRUD application. 我正在开发ColdFusion 8培训应用程序,其中正在提出一些AJAX请求(没有jQuery之类的任何库)以支持非常基本的CRUD应用程序。 The high level architecture includes a CFM view, a CFC with remote access methods which receive the AJAX requests, and a CFC which acts as a model and has all of the database queries. 高级体系结构包括CFM视图,具有接收AJAX请求的远程访问方法的CFC,以及充当模型并具有所有数据库查询的CFC。 For just retrieving data that doesn't require any sort of bind variables (like getting all rows from the table), the AJAX queries are working fine. 对于仅检索不需要任何绑定变量(例如从表中获取所有行)的数据,AJAX查询工作正常。 When I try to post anything to the CFC middle layer, however, I'm getting errors about the values I'm looking for being undefined in the Form scope (which from my understanding is where post parameters will be stored). 但是,当我尝试将任何内容发布到CFC中间层时,我在Form范围(根据我的理解是将存储发布参数的位置)中寻找的未定义值中遇到错误。 I even dissected the requests with Tamper Data and verified that the names and values of the post parameters are as I expect them to be. 我什至使用Tamper Data剖析了请求,并验证了post参数的名称和值是否符合我的期望。

Here is an example of the JS AJAX requests: 这是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;
        }

Essentially what's happening on the page is that a table populated by all the location (loc) records is being rendered for a "user". 本质上,页面上发生的事情是为“用户”呈现了由所有位置(loc)记录填充的表。 There is a form to add a new user, and when they click the add button, a Loc structure is created containing the information they entered and is passed to the addLocation function. 有一个添加新用户的表单,当他们单击添加按钮时,将创建一个Loc结构,其中包含他们输入的信息并将其传递给addLocation函数。 This creates an Access structure, which will include the request URL, method, the name of a function to act as a callback, and any post parameters. 这将创建一个Access结构,其中将包括请求URL,方法,用作回调的函数的名称以及任何post参数。 This is all passed into the accessWrapper function, which will create the XMLHttpRequest and process the AJAX request. 所有这些都传递给accessWrapper函数,该函数将创建XMLHttpRequest并处理AJAX请求。 I used a closure for the onreadystatechange callback function so that it could be aware of the XMLHttpRequest object and the callback function defined in the Access structure (this callback function will be generally be used to refresh the view table after a record is added, deleted, or edited). 我为onreadystatechange回调函数使用了一个闭包,以便它可以知道XMLHttpRequest对象和Access结构中定义的回调函数(此回调函数通常用于在添加,删除记录后刷新视图表,或编辑)。

Here is the cffunction within the middle-layer CFC where the problem is being reported from. 这是报告问题的中间层CFC中的cffunction。 I won't bother to post the DAO CFC as that has been tested elsewhere and is not even being reached during this process (because it's failing at the middle [or controller] level) 我不会费心发布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>

The error in the request response is: 500 Element NEWLOC is undefined in FORM 请求响应中的错误是:FORM中未定义500元素NEWLOC

Like I said before, I've checked the request in Tamper Data, and it looks fine there. 就像我之前说过的那样,我已经在篡改数据中检查了该请求,在那里看起来还不错。 Thanks in advance for any help you great folks might be able to offer! 在此先感谢您伟大的人们可能提供的任何帮助!

There absolutely is a FORM scope when you do an Ajax post to a CFC. 当您向CFC进行Ajax发布时,绝对有一个FORM范围。

This example POSTs form data via Ajax to a CFC function with no arguments and returns the JSON format of the FORM scope. 本示例通过Ajax将表单数据POST到不带参数的CFC函数中并返回FORM范围的JSON格式。 Yes, you should have arguments to document, specify required/not required and data type, but they're not mandatory. 是的,您应该有用于文档的参数,指定必需/不需要和数据类型,但是它们不是强制性的。

Is there any reason you aren't using jQuery? 您是否没有使用jQuery的任何原因? It would probably make your life much easier. 这可能会使您的生活更加轻松。

There must be something wrong with how you're sending the form data to the Ajax call. 将表单数据发送到Ajax调用的方式一定存在问题。 If you use FireBug to watch your Ajax calls, you can see the POSTed parameters. 如果使用FireBug观看Ajax呼叫,则可以看到POSTed参数。

HTML 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 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 CFC

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


Old School, no jQuery, just plain ol' JavaScript 老派,没有jQuery,只是普通的JavaScript

I found a simple example of an Ajax POST without jQuery here: http://www.openjs.com/articles/ajax_xmlhttp_using_post.php 我在这里找到了一个没有jQuery的Ajax POST的简单示例: http : //www.openjs.com/articles/ajax_xmlhttp_using_post.php

HTML HTML
Remove the jQuery SCRIPT tag, change the other SCRIPT to test-nojq.js and change the submit button to add an onclick event. 删除jQuery SCRIPT标记,将另一个SCRIPT更改为test-nojq.js,并更改Submit按钮以添加onclick事件。

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

JavaScript: test-nojq.js 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);
}

Make newLoc into an argument and it should work. newLoc参数,它应该可以工作。

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

</cffunction>

update: not sure why I encountered no form scope one time calling a remote method. 更新:不确定为什么一次调用远程方法时没有遇到任何窗体作用域。 Anyway, it isn't true but the rest of the answer should still hold true. 无论如何,这是不正确的,但其余答案仍然适用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM