在Ajax获取请求后,Spring Controller未返回html页面

时间:2018-04-06 12:13:26

标签: javascript ajax spring-mvc

所以我有一个"折扣" 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注释已添加到控制器方法,问题仍然存在

1 个答案:

答案 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);
});