Ajax 调用未通过 GRAILS 控制器上的 withFormat->json

Posted

技术标签:

【中文标题】Ajax 调用未通过 GRAILS 控制器上的 withFormat->json【英文标题】:Ajax call is not going through the withFormat->json on GRAILS controller 【发布时间】:2012-11-04 11:55:58 【问题描述】:

我有一个 gsp 页面,其中包含一个执行 ajax 调用的 JS 函数(名为“sample”)。

function sample() 
         var params =  office: id: "testId", population: id: "testId2";

        $.ajax(
            url: "http://localhost:8080/officeProj/mustache/list",
            cache: false,
            contentType: "application/json; charset=utf-8",
            type: "POST",
            dataType: "json",
            data: JSON.stringify(params),
            complete:function(json)
                console.log(" reponse :"+ json);
            ,
            success: function(officeData) 
                var template = "<h1>data.firstName data.lastName</h1>";
                var html = Mustache.to_html(template, data);
                $('#sampleArea').html(html);
             ,
            error: function (XMLHttpRequest, textStatus, errorThrown) 
                console.log("error :"+XMLHttpRequest.responseText);
            
        )

    

现在,这个 ajax 调用到达适当的 GRAILS 控制器和适当的操作,定义为:

def list = 

    withFormat 
        html  return [title: "Mustache" , data:[firstName:"Indiana", lastName:"Jones"], address:"NYC" ] 
        json 
            // extract the data to be rendered to the page
            println("processing JSON.....")
            render ([title: "Mustache" , data:[firstName:"Indiana", lastName:"Jones"], address:"NYC" ] as JSON)
        
    

问题是控件从不通过控制器操作中的 withFormat->json,因此我没有看到预期的结果。(当控件返回 gsp 页面时,它通过“完整" 但没有通过“成功”。没有记录错误。任何人都可以看到我的 ajax 调用有任何问题吗?如果我需要提供更多信息,请告诉我。提前谢谢。

【问题讨论】:

【参考方案1】:

尽管您的问题似乎已经解决,但我还是想提一下这背后的真正原因。

问题似乎出在 grails 进行内容协商的方式上。

根据 grails 文档,grails 将寻找接受标头,这将决定响应格式。

但这里的问题是,默认情况下,在 config.groovy 中,grails.mime.use.accept.header = false,它基本上忽略了接受标头,所以即使您在您的ajax 请求(这会将接受头设置为“application/json”),它不会寻找接受头,响应格式将始终为“全部”,这是默认值。

所以基本上设置 grails.mime.use.accept.header = true,将解决问题。

希望对你有帮助

【讨论】:

【参考方案2】:

这通常会引起人们的注意,尤其是在从 Grails 1.x 迁移到 Grails 2.x 时。你必须仔细阅读docco。

粗体字是我的...

另一个需要注意的重要因素是 withFormat 方法处理 response 格式而不是 request 格式。从 Grails 2.0 开始, 根据请求提供了一个单独的 withFormat 方法 您可以使用它来处理由 请求的 CONTENT_TYPE 标头:

request.withFormat 
    xml  .. 
    html  .. 

【讨论】:

来自文档 (docs.grails.org/3.1.1/ref/Controllers/withFormat.html) “...根据传入的请求 Accept 标头、格式参数或 URI 扩展呈现不同的响应。”从 ajax 调用中,*** dataType: "json" *** 将 Accept 标头设置为 application/json,这不是请求格式,而是所需的响应格式。仍然 withFormat 不匹配“json”(在 grails 2.5.3 上测试)。 onekilo79.wordpress.com/2014/02/11/… .get('/book/index.json') 诀窍是将 .json 添加到 url 的末尾 - withFormat 工作正常 - url: "$createLink(controller: 'someController',action:'someAction.json')", data:id:$instance.id,【参考方案3】:

另一个潜在的解决方案。

文档说:

请注意,类型的顺序很重要如果请求格式为“全部”,或者如果多个内容类型在接受标头中具有相同的“q”等级。在前一种情况下,块中的第一个类型处理程序被执行

我认为这意味着如果您的 Accept 标头看起来像这样:

Accept:application/json, text/javascript, */*; q=0.01

*/* 表示全部接受,这意味着将使用第一个处理程序,而不管其余的处理程序。

快速解决方案:将 html 闭包移到最后。

【讨论】:

【参考方案4】:

Grails 默认忽略浏览器的接受标头。阅读content negotiation

文本/xml, 应用程序/xml, 应用程序/xhtml+xml, 文本/html;q=0.9, text/plain;q=0.8, image/png, /;q=0.5

这个特定的接受标头没有帮助,因为它表明 XML 是首选的响应格式,而用户实际上是 期待 HTML。这就是Grails默认忽略accept header的原因 对于浏览器。

grails.mime.disable.accept.header.userAgents 控制哪些浏览器接受标题 grails 将忽略

【讨论】:

以上是关于Ajax 调用未通过 GRAILS 控制器上的 withFormat->json的主要内容,如果未能解决你的问题,请参考以下文章

从 grails 中的 gsp 页面进行 ajax 调用

在 grails 控制器中识别 ajax 请求或浏览器请求

ajax请求在spring security中被拒绝,Grails

热实现 grails 服务器端触发对话框,或如何在 AJAX 调用后突破更新区域

将 AJAX POST 的参数传递给 Grails 控制器

rails 控制器未收到 Ajax 调用