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的主要内容,如果未能解决你的问题,请参考以下文章
ajax请求在spring security中被拒绝,Grails