我正在尝试使用AJAX POST将我在第三方JS功能(支付网关)的回调函数中获得的响应保存到我的服务器但是我得到的状态代码为 - 405 Method Not Allowed。我得到的回复是 - 消息:请求方法' POST'不受支持,说明:请求的资源不允许使用指定的HTTP方法。
我有以下 Javascript客户端代码 -
gateway.pay(token, {
onSuccess : function(result) {
console.log(result);
saveTransactionResult(result);
},
onError : function(result) {
//
},
onClose : function() {
//
}
});
.....
saveTransactionResult : function(result) { // save result to server.
$.ajax({
headers : {
Accept : "text/plain",
"Content-Type" : "application/json"
},
url : "/myshop/checkout/payment/complete",
type : "POST",
data : JSON.stringify(result),
dataType : "text",
success : function(data) {
console.log(data);
console.log("Payment Details have been saved!");
},
error : function() {
console.log("an error has occurred while posting response!");
}
});
}
对应的服务器端Spring MVC处理程序 -
@ResponseBody
@RequestMapping(value = "/complete", method = RequestMethod.POST, consumes =
{ "application/json" })
public String saveResponse(@RequestBody final ResponseData responseData)
{
final boolean result = paymentService.savePayment(responseData);
if (result)
{
return "Success";
}
else
{
return "Failure";
}
}
StackOverflow上的大部分答案都不允许" 405方法"导致与跨域请求相关的问题,但我不确定我的请求是否是跨浏览器请求,因为它是由第三方js的回调中编写的本地代码调用的。如果不是这样,那么我的请求标头或Ajax公式只是一个问题吗? Ajax请求是否必须具有带注释@ResponseBody的处理程序,即使它在功能上不想返回特定于浏览器的任何内容?
我在Chrome上分析此Ajax请求时注意到的另一件事是,CSRFToken会自动以下列方式附加到请求有效负载上 -
{"response":"from","payment":"gateway"}&CSRFToken=7c4c40-b4c4c-44cd3-94c4-a44c437
这可能是导致问题的原因吗?如果是这样,我是否需要在请求处理程序中对此CSRF令牌进行任何特定处理?
PS - 我添加了ajax"标题"正如我之前收到的415(不支持的媒体类型)状态代码没有它们,正如本文中所建议的那样 - POST JSON fails with 415 Unsupported media type, Spring 3 mvc但现在我有了405!
答案 0 :(得分:0)
所以问题在于我的请求被过滤掉了org.springframework.security.web.csrf.CsrfFilter,因为在请求标头或请求参数中找不到服务器端的CSRF令牌。
在客户端,请求有效负载中的CSRFToken附加了一个通用的应用程序范围的$ .ajaxPrefilter函数,该函数负责以不同的方式将CSRFToken添加到整个应用程序中的所有POST Ajax请求。有效负载的内容类型。看看这个函数,我意识到一般的经验法则是,如果数据类型为window.FormData,则将CSRFToken附加到AJAX请求的“data”字段中,并将CSRFToken添加到Ajax请求的头部。数据类型为“application / json”,如下所示 -
jqXHR.setRequestHeader('CSRFToken', ACC.config.CSRFToken);
通过向application / json显式指定Ajax参数contentType,我的ajaxPrefilter能够正确地将CSRFToken放入Request Header,而不是将其与JSON请求有效负载一起附加。以下请求使其有效 -
saveTransactionResult : function(result) { // save result to server.
$.ajax({
headers : {
Accept : "text/plain",
"Content-Type" : "application/json"
},
url : "/myshop/checkout/payment/complete",
type : "POST",
data : JSON.stringify(result),
dataType : "text",
contentType : "application/json; charset=utf-8",
success : function(data) {
console.log(data);
console.log("Payment Details have been saved!");
},
error : function() {
console.log("an error has occurred while posting response!");
}
});
}