【问题标题】:Grails controller sending weird JSON back to browserGrails 控制器将奇怪的 JSON 发送回浏览器
【发布时间】:2014-10-28 12:35:08
【问题描述】:

我有一个 Grails (2.3.6) 应用程序提供一个 HTML 表单,其中包含两个 <select/> 元素:一个允许用户选择 country,然后选择 state。当用户选择一个新的country 时,我想更新state 选择元素。为此,在国家 change() 上,我需要向服务器询问新的状态选项列表以填充状态 <select/>

<div class="blah">
    <label for="state">State</label><br/>
    <g:select id="state" name="state" from="${states}" />
</div>

<script type="text/javascript">
    jQuery('#country').change(function() {
        var countryName = $('#country option:selected').val();

        jQuery.ajax({
            url: "getStateListByCountry",
            type:"get",
            dataType: 'json',
            data: {
                countryName: countryName
            },
            success: function(data) {
                alert("Received following from server: " + data);

                $("#state option").remove();

                $.each(data, function(key, value) {
                    $('#state')
                        .append($("<option></option>")
                        .attr("value",key)
                        .text(value));
                });
            },
            error: function(xhr){
                alert(xhr.responseText); //<----TODO: Replace
            }
        });
    });
</script>

然后,在 Grails/服务器端:

class MyController {
    // Stub this with dummy data to return.
    def getStateListByCountry() {
        List<String> states = new ArrayList<String>()
        states.add("NY")
        states.add("NH")
        states.add("VT")

        println "Sending the following back to browser: ${states}."

        states
    }       
}

在运行时,当我在“#country”选择中选择一个新国家/地区时,我在 Grails 应用程序日志中看到以下消息:

将以下内容发送回浏览器:[NY, NH, VT]。

然后在浏览器中我得到一个alert(...),它打印我的自定义“未找到页面”错误页面的 HTML!

此外,我的“#state”选择不会使用 3 个虚拟状态值进行更新。因此,Grails 服务器正确接收客户端请求,并尝试发回我的虚拟状态列表,但在某处返回“未找到页面”模板。关于这里发生了什么或我的代码有什么问题的任何想法?


更新

似乎我的error 函数正在执行,而我在alert 中看到的奇怪HTML 实际上是传递给该方法的xhr.responseText

Grails 服务器没有在日志中报告任何错误,getStateListByCountry 方法中的println 确认返回给客户端的 JSON 是 ["NY","VT","NH"]。所以似乎服务器以某种方式返回错误,并且 jQuery 正在执行 error 处理程序,不是 success 处理程序......想法?

【问题讨论】:

  • 您可以使用 grails 模板更新“状态”,我认为这比通过 javascript 处理所有事情要容易得多。
  • 谢谢@Abdullah (+1) - 我不熟悉这个“模板”概念 - 你介意分享一个链接或 jsFiddle/gist 来了解它是如何工作的吗?再次感谢!
  • 发送 JSON 使用 states as JSON
  • 您的代码一切正常,只需要从控制器发送响应,例如:render states as grails.converters.JSON
  • 为什么会被否决?这是一个 SSCCE,展示了研究,展示了努力,而不是欺骗。

标签: jquery ajax grails grails-controller


【解决方案1】:

尝试在状态中添加:“as JSON”:

states as JSON

编辑:

smeeb,我这里做了个测试环境,改了你的:

jQuery.ajax({
    url: "controllername/getStateListByCountry",
    type: "get",
    data: countryName,

在action前使用controllername,不需要dataType,返回:

render states as JSON

它成功了,你可以试试吗?

【讨论】:

  • 感谢@Vitor Hugo (+1) - 但这并不能解决我的问题;同样的问题。还有其他想法吗?
  • 另外,请查看我的更新,error 处理程序正在执行,这就是为什么我看到来自服务器的奇怪响应文本...
【解决方案2】:

调用更改国家/地区的函数

   jQuery('#country').change(function() {

    jQuery.ajax({
        url: "getStateListByCountry",
        type:"get",
        dataType: 'json',
        data: {
            countryName: countryName
        },
       success: function(data) {
        $('#divId').replaceWith(data);

    }

并在指定的 url getStateListByCountry 上检索 states 并从那里渲染一个模板

render template: 'nameOfTemplate', model: [states:States.list()]

然后在成功回调中用新模板替换 div。

您应该在模板中放置 g:select 框并使用模型中传递的状态列表填充该选择框。 您可以在创建视图时创建模板,只需在模板名称前添加下划线 "_"。更多关于Templates and Views

【讨论】:

  • 感谢@Abdullah (+1) - 虽然这是一个有趣的解决方案,但我对这个特定问题不感兴趣。请看我的更新;看起来error 处理程序正在执行,这就是为什么我看到奇怪的响应文本。有任何想法吗?再次感谢!
【解决方案3】:

问题出在客户端。我已经指定了“json”的dataType,但没有通过 Grails render(...) 方法返回 JSON。

【讨论】:

  • 我在回答中添加了一些内容,请查看。
  • 关于赏金:它不像你预期的那样工作。看看How bounty is awarded(你不能奖励自己的答案。):)
  • 感谢@dmahapatro,但我的本意绝不是奖励自己赏金。这就像给自己零息贷款一样;为什么要这样做?
猜你喜欢
  • 2022-08-03
  • 1970-01-01
  • 2020-06-12
  • 2011-08-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-09-10
相关资源
最近更新 更多