所以我有一个"折扣" html页面,提示用户输入促销代码,通过使用按钮OnClick的Ajax GET请求,我能够将此促销代码传输到我的spring控制器,在那里我适当地操作数据。
出于某种原因,我无法返回"来自此控制器的新页面,我的服务器端没有任何明显的错误,但在我的客户端,我收到此错误:
我不确定这是否相关或相关。
我想知道我的逻辑是否存在这个缺陷,或者我没有实现正确的语法来在AJAX调用之后返回一个新页面。
注意:AJAX请求工作正常,因为我能够使用相关信息将system.out.print获取到控制器底部的控制台。我通过了。
这是我的HTML代码:
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta name="viewport" content="width=device-width, initial-scale=1"></meta>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css"></link>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<script type="text/javascript">
function myFunction(){
var code = document.getElementById("code").value;
var price = document.getElementById("price").value;
$.ajax({
type: "GET",
url: "/calculateDiscount",
data: {
code: code
}, // parameters
contentType: "application/json; charset=utf-8",
datatype: 'json'
//alert(status);
});
}
</script>
</head>
<body>
<div>
<center>
<h3>Total Price: $<text th:text="${totalPrice}" id="price"/> </h3>
<input type="text" name="firstname" id="code">
<button onclick="myFunction()">Calculate Discount</button>
<a style="color:blue" th:href="@{/welcome}">HomeScreen!</a>
<br />
<!-- <a style="color:blue" th:if="${myteam != null}" th:href="@{/leaveteam/{id}(id=${myteam?.id})}">Leave Team?!</a>
-->
</center>
</div>
</body>
</html>
控制器:
@RequestMapping(value="/calculateDiscount", method=RequestMethod.GET)
@ResponseBody
public String CalculateDiscount(Model model, @RequestParam("code") String code, RedirectAttributes redirectAttributes) {
///need to calculate price if codes correct then return page with card info then after proceed call purchasebooks controller!
System.out.println("Price: " + code );
Authentication loggedInUser = SecurityContextHolder.getContext().getAuthentication();
String email = loggedInUser.getName();
UserLogin user = uR.findByUserName(email);
int totalPrice = 0;
if (code.equals("Discount1010"))
{
Set<Book> books = user.getBooks();
for (Book b : books)
{
totalPrice = totalPrice + b.getPrice();
}
int discountPrice = (int) (totalPrice * .80);
model.addAttribute("totalPrice", totalPrice);
System.out.println("Price: " + discountPrice );
}
else {
Set<Book> books = user.getBooks();
for (Book b : books)
{
totalPrice = totalPrice + b.getPrice();
}
System.out.println("Price: " + totalPrice );
model.addAttribute("totalPrice", totalPrice);
}
return "payment";
}
我想要返回的页面:
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta name="viewport" content="width=device-width, initial-scale=1"></meta>
<title>Insert title here</title>
</head>
<body>
<h3>Total Price: $<text th:text="${totalPrice}" id="price"/> </h3>
</body>
</html>
需要更多信息让我知道。
ķ。
编辑:在回答下面的一个答案时,我确实禁用了csrf。 这是我的WebSecurityConfig类:
@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
UserLoginRepository userLoginRepository;
//http.authorizeRequests().antMatchers("/", "/home", "/registeruser").permitAll().antMatchers("/admin").hasRole("ADMIN")
@Autowired
DataSource dataSource;
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests().antMatchers("/", "/home", "/registeruser").permitAll().antMatchers("/admin").hasRole("ADMIN")
.anyRequest().authenticated().and().formLogin().loginPage("/login").permitAll().and().logout()
.permitAll();
http.exceptionHandling().accessDeniedPage("/403");
http.csrf().disable();
//disable csrf to allow communication (we also dont need for this fyp as its not live)
}
@Override
public void configure(WebSecurity web) {
web.ignoring().antMatchers("/fonts/**", "/images/**", "/css/**");
}
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth.jdbcAuthentication().dataSource(dataSource)
.usersByUsernameQuery("select user_name,password,user_status from user_login where user_name=?")
.authoritiesByUsernameQuery("select user_name, password from user_login where user_name=?");
}
@Bean
public static NoOpPasswordEncoder passwordEncoder() {
return (NoOpPasswordEncoder) NoOpPasswordEncoder.getInstance();
}
}
更新:@ResponseBody注释已添加到控制器方法,问题仍然存在
答案 0 :(得分:1)
我想这是CSRF问题。您已实施Spring Security(我可以看到
SecurityContexHolder
类)并且可能启用了csrf - 这是默认设置。如果你想禁用它,只需使用这个
Java配置:
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable();
}
XML:
<http>
<!-- ... -->
<csrf disabled="true"/>
</http>
但是如果你想保持csrf,你需要将csrf标记传递给ajax标头。为此,请将csrf包含在元标记中:
<head>
<meta name="_csrf" th:content="${_csrf.token}"/>
<meta name="_csrf_header" th:content="${_csrf.headerName}"/>
然后将csrf包含在Ajax请求中:
var token = /*[[${_csrf.token}]]*/ '';
var header = /*[[${_csrf.headerName}]]*/ '';
$(document).ajaxSend(function(e,xhr,options) {
xhr.setRequestHeader(header, token);
});