0

我正在导航indexMyController. 页面上的一些代码正在对inindex进行 AJAX 调用。我希望操作将一些数据作为 JSON 返回到我的 AJAX 调用,以便我可以对数据客户端做一些事情,但不是像我想要的那样将数据作为 JSON 返回,而是将数据显示为文本。myActionMyControllermyAction

我的 Grails 控制器示例:

class MyController {
    def index() {
        render( view: "myView" )
    }

    def myAction {
        def mapOfStuff = [ "foo": "foo", "bar": "bar" ]
        render mapOfStuff as JSON
    }
}

我的 JavaScript 示例:

$( function() {
    function callMyAction() {
        $.ajax({
            dataType: 'json',
            url: base_url + '/myController/myAction',
            success: function( data ) {
                $(function() {
                    if( data.foo ) {
                        alert( data.foo );
                    }
                    if( data.bar ) {
                        alert( data.bar );
                    }
                });
            }
        });
    }
});

我期望的是我的页面将呈现,然后我的 JavaScript 将被调用,然后将显示两个警报。相反,JSON 数组在我的浏览器窗口中显示为文本:

{"foo":"foo","bar":"bar"}

此时,我的地址栏中 URL 的最后一段是myAction而不是index. 现在,如果我手动输入索引页面的 URL 并按刷新,一切都会按预期工作。

我有六个 AJAX 调用,我以完全相同的方式进行调用,但没有一个有问题。这里有什么交易?

更新#1:

我注意到了一些事情。当我在操作中设置一个断点并在index操作中设置MyController另一个myAction断点时myActionindex即使我正在导航到index. 事实上,index动作中的断点永远不会被击中。这显然更接近我的问题的根本原因,但为什么会发生呢?

更新#2:

我正在使用 Spring Security,我注意到即使我将默认 URL 设置为...

grails.plugins.springsecurity.successHandler.defaultTargetUrl = '/myController'

...登录时,“索引”操作中的断点MyController从未被击中,但myView已正确呈现。Spring Security 在做什么样的黑魔法,它可以在不通过我的控制器的情况下加载我的视图?

更新#3:

我找到了解决这个问题的方法,问题是 Spring Security 在后台做了一些奇怪的事情。所以我只是添加alwaysUseDefault到我的配置中并将其设置为 true,如下所示:

grails.plugins.springsecurity.successHandler.alwaysUseDefault = true

现在我击中了在断点被击中之前的index动作中设置的断点,正如我所期望的那样。不幸的是,这个解决方案并不是最优的,因为用户现在总是被重定向到登录后,即使他们试图导航到不同的页面。MyControllermyActiondefaultTargetUrl

虽然这种解决方案解决了我的问题,但它提出了一个问题,Spring Security 是如何重定向到我的defaultTargetUrl,它是这样设置的......

grails.plugins.springsecurity.successHandler.defaultTargetUrl = '/myController'

...没有经过的index动作MyController

4

3 回答 3

1

尝试使用:

def mapOfStuff = [ foo: "foo", bar:"bar"]

而不是将键用作 Groovy 字符串。

于 2012-10-15T22:47:34.957 回答
1

IIRC,不要render mapOfStuff as JSON,但是return mapOfStuff as JSON。它将为响应分配适当的内容类型标头。

render()只是一个返回 a 的函数,String它被渲染为text/html,因为 Grails 无法检测到其中的内容。JSON类型 OTOH 以适当的内容类型呈现。

于 2012-10-16T13:31:17.410 回答
0

明确设置适当的响应标头。

render(contentType: "text/json") {  
  def mapOfStuff = [ "foo": "foo", "bar": "bar" ]
}
于 2015-01-17T13:06:13.887 回答