Groovy应用接收POST凭证异常:AngularJS提交的参数无法解析
问题分析与解决方案
从你描述的情况来看,核心问题出在请求的Content-Type和数据格式不匹配:你设置了Content-Type: application/x-www-form-urlencoded,但发送的是JSON对象,AngularJS并不会自动把JSON转换成表单编码的格式,导致后端收到的是一个奇怪的参数结构(JSON字符串作为键,值为空),所以无论用params.j_username还是request.JSON.j_username都拿不到正确的值。
下面给你两种可行的解决方案:
方案1:将数据转换为表单编码格式发送
既然你指定了表单编码的Content-Type,就需要把JSON对象转换成key1=value1&key2=value2的格式。你可以用两种方式实现:
方式A:借助jQuery的$.param方法
如果你的项目已经引入了jQuery,直接用它的序列化方法:
vm.login = function(){ $http({ method: 'POST', url: "http://t0002161750:8080/TERA/authAuto", data: $.param({ j_username: vm.user.username, j_password: vm.user.password, instance: "http://t0002161750:8080/TERA/authAuto" }), headers:{ 'Content-Type': 'application/x-www-form-urlencoded;charset=utf8' } }).success(function(response){ $window.location.href = "http://t0002161750:8080/TERA/"; }); }
这样后端就能通过params.j_username、params.j_password正常获取参数了。
方式B:自定义序列化函数(无需jQuery)
如果不想引入jQuery,自己写一个简单的序列化函数:
function serializeFormData(obj) { let parts = []; for (let key in obj) { if (obj.hasOwnProperty(key)) { parts.push(encodeURIComponent(key) + '=' + encodeURIComponent(obj[key])); } } return parts.join('&'); } // 然后在请求中使用 vm.login = function(){ $http({ method: 'POST', url: "http://t0002161750:8080/TERA/authAuto", data: serializeFormData({ j_username: vm.user.username, j_password: vm.user.password, instance: "http://t0002161750:8080/TERA/authAuto" }), headers:{ 'Content-Type': 'application/x-www-form-urlencoded;charset=utf8' } }).success(function(response){ $window.location.href = "http://t0002161750:8080/TERA/"; }); }
方案2:后端改为接收JSON格式请求
如果后端允许修改,更简单的方式是保持前端发送JSON数据,同时把Content-Type改成application/json,这样后端就能用request.JSON.j_username获取参数了:
前端修改:
vm.login = function(){ $http({ method: 'POST', url: "http://t0002161750:8080/TERA/authAuto", data: { j_username: vm.user.username, j_password: vm.user.password, instance: "http://t0002161750:8080/TERA/authAuto" }, headers:{ 'Content-Type': 'application/json;charset=utf8' } }).success(function(response){ $window.location.href = "http://t0002161750:8080/TERA/"; }); }
后端Groovy/Grails修改:
确保你的Grails控制器能解析JSON请求,Grails默认是支持的,直接用:
def authAuto() { def username = request.JSON.j_username def password = request.JSON.j_password // 后续逻辑... }
这个方案更符合现代API的设计风格,也避免了表单序列化的麻烦,而且同样不会把凭证暴露在URL中,完全满足你的需求。
内容的提问来源于stack exchange,提问作者AndiFB
相关产品推荐
相关产品推荐

