【问题标题】:405 Method Not Allowed : Request method 'POST' not supported | Ajax/Spring MVC405 方法不允许:不支持请求方法“POST”| Ajax/Spring MVC
【发布时间】:2018-08-19 19:22:48
【问题描述】:

我正在尝试使用 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!");
        }
    });
}

对应的Server-side Spring MVC Handler -

@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 Method not allowed”的大多数答案都导致与跨域请求相关的问题,但我不确定我的请求是否是跨浏览器请求,因为它是由回调中编写的本地代码调用的第三方js。如果不是这种情况,这仅仅是我的请求标头或 Ajax 公式的问题吗? Ajax 请求是否必须有一个带有注释 @ResponseBody 的处理程序,即使它在功能上不希望返回任何特定于浏览器的内容?

我在 Chrome 上分析此 Ajax 请求时注意到的另一件事是 CSRFToken 以下列方式自动附加到请求有效负载 -

{"response":"from","payment":"gateway"}&CSRFToken=7c4c40-b4c4c-44cd3-94c4-a44c437

这是导致问题的原因吗?如果是这样,我是否需要在我的请求处理程序中对这个 CSRF Token 做任何特定的处理?

PS - 我已经添加了 ajax“标题”,因为我之前在没有它们的情况下获得了 415(不支持的媒体类型)状态代码,正如这篇文章中所建议的 - POST JSON fails with 415 Unsupported media type, Spring 3 mvc 但现在我有一个 405!

【问题讨论】:

  • 您发布到 url“/myshop/checkout/payment/complete”,但控制器映射值为“/complete”。可能,问题来了?
  • 不,这不是问题。 “/complete”是我的处理程序方法的映射。 url 的其余部分由我的控制器顶部的 RequestMapping 处理。

标签: javascript java jquery ajax spring-mvc


【解决方案1】:

所以问题在于我的请求在 org.springframework.security.web.csrf.CsrfFilter 中被过滤掉了,因为在请求标头或请求参数中都没有在服务器端找到 CSRF 令牌。

在客户端,请求负载中的 CSRFToken 被一个通用应用程序范围的 $.ajaxPrefilter 函数附加,该函数负责以不同的方式将 CSRFToken 添加到整个应用程序中的所有 POST Ajax 请求,对应于有效负载的内容类型。看看这个函数,我意识到一般的经验法则是,如果数据是 window.FormData 类型,则将 CSRFToken 添加到 AJAX 请求的“数据”字段中,然后将 CSRFToken 添加到 Ajax 请求的标头中,如果数据的类型为“application/json”,如下 -

jqXHR.setRequestHeader('CSRFToken', ACC.config.CSRFToken);

通过将 Ajax 参数 contentType 显式指定为 application/json,我的 ajaxPrefilter 能够正确地将 CSRFToken 放入请求标头中,而不是将其与 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!");
        }
    });
}

【讨论】:

    猜你喜欢
    • 2020-07-24
    • 2020-08-12
    • 2014-06-10
    • 2018-07-24
    • 2017-07-01
    • 1970-01-01
    • 2012-06-24
    • 2015-04-09
    • 2016-03-29
    相关资源
    最近更新 更多