【问题标题】:Ajax call is not going through the withFormat->json on GRAILS controllerAjax 调用未通过 GRAILS 控制器上的 withFormat->json
【发布时间】: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 调用有任何问题吗?如果我需要提供更多信息,请告诉我。提前谢谢。

【问题讨论】:

    标签: jquery grails


    【解决方案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 将忽略

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2020-07-16
          • 2017-09-20
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2015-05-17
          • 2012-06-25
          相关资源
          最近更新 更多