Ajax POST 结果为 405(方法不允许)- Spring MVC
Ajax POST results in a 405 (Method Not Allowed) - Spring MVC
我正在尝试使用 POST 方法对我的 Spring controller/action 进行 ajax 调用,并且 return 来自服务器的对象@ResponseBody。奇怪的是,添加 spring 安全层后它停止工作,之前一切正常。我将尝试解释我解决问题的步骤,然后向您展示 code/captures/etc.
1。
经过一些研究,我发现一些答案告诉我这个问题可能与 csrf 机制有关,所以我禁用它但问题仍然存在。 (spring-security.xml 如下)
2。
我做了一个 wireshark 捕获来检查 request/response。我的 ajax 请求没问题,我的控制器声明没问题,但我不明白为什么,405 响应指示 > Allow: GET (capture bellow)
3。
我试图通过浏览器访问我的控制器操作(即发出 GET 请求),但我收到错误 HTTP 状态 405 - 不支持请求方法 'GET'!
4。
我试图将 RequestMapping(method...) 更改为 RequestMethod.GET 并且请求到达控制器并且工作正常,但我不希望它在 GET 方法上工作,我想要一个 POST请求。
5。
更改了 RequestMapping(consumes, produces, headers) 以接受所有类型的数据,但仍然是 405...
这让我发疯!我 post 我的文件在下面,所以你们可以检查一下,任何提示都将不胜感激。谢谢! (重要提示:这是我的绝望配置)
spring-security.xml
<beans:beans
xmlns...(all needed declarations)>
<http pattern="/js/**" security="none" />
<http pattern="/css/**" security="none" />
<!-- enable use-expressions -->
<http auto-config="true" >
<access-denied-handler error-page="/403" />
<intercept-url pattern="/admin/**" access="hasRole('ROLE_ADMIN')" />
<intercept-url pattern="/login" access="isAnonymous()" />
<intercept-url pattern="/403" access="permitAll" />
<intercept-url pattern="/**" access="hasRole('ROLE_USER')" />
<form-login login-page="/login"
username-parameter="email"
password-parameter="password"
authentication-failure-url="/login?failed" />
<!--
<csrf/>
-->
</http>
..... (authentication)
AdminController.java
@Controller
@RequestMapping("/admin**")
public class AdminController {
... (all my autowired beans)
@RequestMapping(
value = "/events/loadEvents",
method = RequestMethod.POST,
consumes = MediaType.ALL_VALUE,
produces = MediaType.ALL_VALUE,
headers = "Accept=*/*")
@ResponseBody
public Event loadEvents(@RequestParam("parentId") long parentId) {
... (my logic)
return event;
}
}
请求(wireshark抓包)
响应(wireshark抓包)
编辑
jqueryajax调用代码
$.ajax({
type: 'POST',
cache: false,
url: /admin/events/loadEvents,
data: { parentId: 1 },
dataType = 'json',
contentType = 'application/json',
...
});
经过几个小时的研究和测试,我终于明白了,这是一个(非常非常)愚蠢的情况。所以,在我的问题中我说
so I disabled it (csrf on spring-security.xml) and still have the issue.
不,我没有禁用它。我试图禁用它做
<!--
<csrf/>
-->
但我应该这样做:
<csrf disabled="true"/>
评论 csrf 标签 不会 禁用 csrf,这是因为默认情况下启用 csrf!发现问题后很容易说这是一个愚蠢的错误,但是当我添加 csrf 标签来启用它时,我认为评论它会禁用它。在 Spring Documentation
上寻找答案
现在,回到我的问题。要在启用 CSRF 的 POST AJAX 调用中修复 405 错误消息,这真的很容易。我将 csrf 参数保存在 JS 变量中,如下所示:
<script type="text/javascript">
var csrfParameter = '${_csrf.parameterName}';
var csrfToken = '${_csrf.token}';
</script>
然后我的 ajax 调用如下所示:
var jsonParams = {};
jsonParams['parentId'] = 1;
jsonParams[csrfParameter] = csrfToken;
$.ajax({
type: 'POST',
cache: false,
url: /admin/events/loadEvents,
data: jsonParams,
dataType = 'json',
contentType = 'application/json',
...
});
像魅力一样工作。希望对以后的人有所帮助。
$.ajaxSetup({
dataType: "json",
beforeSend: function(xhr, settings){
var csrftoken = $.cookie('CSRF-TOKEN');
xhr.setRequestHeader("X-CSRF-TOKEN", csrftoken);
},
});
就我而言,遇到同样的问题,对此有帮助:
- 添加标签库:
<%@ taglib prefix="sec" uri="http://www.springframework.org/security/tags" %>
- 在jsp正文中添加:
<sec:csrfMetaTags />
- 加入ajax
headers: {"X-CSRF-TOKEN": $("meta[name='_csrf']").attr("content")}
P.S。感谢 Illya Shulgin,很酷的回答,现在就在这里。
我正在尝试使用 POST 方法对我的 Spring controller/action 进行 ajax 调用,并且 return 来自服务器的对象@ResponseBody。奇怪的是,添加 spring 安全层后它停止工作,之前一切正常。我将尝试解释我解决问题的步骤,然后向您展示 code/captures/etc.
1。 经过一些研究,我发现一些答案告诉我这个问题可能与 csrf 机制有关,所以我禁用它但问题仍然存在。 (spring-security.xml 如下)
2。 我做了一个 wireshark 捕获来检查 request/response。我的 ajax 请求没问题,我的控制器声明没问题,但我不明白为什么,405 响应指示 > Allow: GET (capture bellow)
3。 我试图通过浏览器访问我的控制器操作(即发出 GET 请求),但我收到错误 HTTP 状态 405 - 不支持请求方法 'GET'!
4。 我试图将 RequestMapping(method...) 更改为 RequestMethod.GET 并且请求到达控制器并且工作正常,但我不希望它在 GET 方法上工作,我想要一个 POST请求。
5。 更改了 RequestMapping(consumes, produces, headers) 以接受所有类型的数据,但仍然是 405...
这让我发疯!我 post 我的文件在下面,所以你们可以检查一下,任何提示都将不胜感激。谢谢! (重要提示:这是我的绝望配置)
spring-security.xml
<beans:beans
xmlns...(all needed declarations)>
<http pattern="/js/**" security="none" />
<http pattern="/css/**" security="none" />
<!-- enable use-expressions -->
<http auto-config="true" >
<access-denied-handler error-page="/403" />
<intercept-url pattern="/admin/**" access="hasRole('ROLE_ADMIN')" />
<intercept-url pattern="/login" access="isAnonymous()" />
<intercept-url pattern="/403" access="permitAll" />
<intercept-url pattern="/**" access="hasRole('ROLE_USER')" />
<form-login login-page="/login"
username-parameter="email"
password-parameter="password"
authentication-failure-url="/login?failed" />
<!--
<csrf/>
-->
</http>
..... (authentication)
AdminController.java
@Controller
@RequestMapping("/admin**")
public class AdminController {
... (all my autowired beans)
@RequestMapping(
value = "/events/loadEvents",
method = RequestMethod.POST,
consumes = MediaType.ALL_VALUE,
produces = MediaType.ALL_VALUE,
headers = "Accept=*/*")
@ResponseBody
public Event loadEvents(@RequestParam("parentId") long parentId) {
... (my logic)
return event;
}
}
请求(wireshark抓包)
响应(wireshark抓包)
编辑 jqueryajax调用代码
$.ajax({
type: 'POST',
cache: false,
url: /admin/events/loadEvents,
data: { parentId: 1 },
dataType = 'json',
contentType = 'application/json',
...
});
经过几个小时的研究和测试,我终于明白了,这是一个(非常非常)愚蠢的情况。所以,在我的问题中我说
so I disabled it (csrf on spring-security.xml) and still have the issue.
不,我没有禁用它。我试图禁用它做
<!--
<csrf/>
-->
但我应该这样做:
<csrf disabled="true"/>
评论 csrf 标签 不会 禁用 csrf,这是因为默认情况下启用 csrf!发现问题后很容易说这是一个愚蠢的错误,但是当我添加 csrf 标签来启用它时,我认为评论它会禁用它。在 Spring Documentation
上寻找答案现在,回到我的问题。要在启用 CSRF 的 POST AJAX 调用中修复 405 错误消息,这真的很容易。我将 csrf 参数保存在 JS 变量中,如下所示:
<script type="text/javascript">
var csrfParameter = '${_csrf.parameterName}';
var csrfToken = '${_csrf.token}';
</script>
然后我的 ajax 调用如下所示:
var jsonParams = {};
jsonParams['parentId'] = 1;
jsonParams[csrfParameter] = csrfToken;
$.ajax({
type: 'POST',
cache: false,
url: /admin/events/loadEvents,
data: jsonParams,
dataType = 'json',
contentType = 'application/json',
...
});
像魅力一样工作。希望对以后的人有所帮助。
$.ajaxSetup({
dataType: "json",
beforeSend: function(xhr, settings){
var csrftoken = $.cookie('CSRF-TOKEN');
xhr.setRequestHeader("X-CSRF-TOKEN", csrftoken);
},
});
就我而言,遇到同样的问题,对此有帮助:
- 添加标签库:
<%@ taglib prefix="sec" uri="http://www.springframework.org/security/tags" %>
- 在jsp正文中添加:
<sec:csrfMetaTags />
- 加入ajax
headers: {"X-CSRF-TOKEN": $("meta[name='_csrf']").attr("content")}
P.S。感谢 Illya Shulgin,很酷的回答,现在就在这里。