角JS和Spring MVC @RestController - POST状态0 [英] Angular JS and Spring MVC @RestController - POST status 0

查看:336
本文介绍了角JS和Spring MVC @RestController - POST状态0的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我目前尝试使用的字体端和Spring MVC的后端(@RestController)角度来开发RESTful应用程序。我已经实施一些GET和POST方法来获取或保存数据,但是现在我面临着一个POST方法存在问题:

I am currently try to develop RESTful application using Angular on font-end and Spring MVC on back-end(@RestController). I already have implemented few GET and POST method to fetch or save data, however now I am facing a problem with one POST method:

angular.module("app").factory("BorrowerService", function($http, $log){
   var borrowBook = function(borrow){
    $log.debug("Borrowing book: " );
    $log.debug(borrow);
    $http({
        method: 'POST',
        url: 'Zadanie3/borrow',
        data: borrow
   }).then(function successCallback(response) {
        $log.debug("success");
   }, function errorCallback(response) {
          $log.error("failed to borrow the book");
          $log.error(response);
      });
   };
   return{
    borrowBook: borrowBook
   };
});

POST结果总是与errorCallback输出:

POST result is always errorCallback with output:

failed to borrow the book
Object {data: null, status: 0, config: Object, statusText: ""}

有趣的是,在大多数浏览器(Firefox的除外),这本书其实也借钱。我已经搜查约状态:0响应(也计算器)和可惜的是还没有找到正确的解决我的问题。我想AP preciate任何帮助。在这里,我RestController方式:

Interesting part is that on most browsers (except Firefox) the book actually do borrow. I have already searched about status:0 response (also on stackoverflow) and unfortunatelly have not found the correct solution to my problem. I would appreciate any help. Here my RestController method:

@RestController
public class BookRestPostController {

 @RequestMapping(value = "/borrow", method=RequestMethod.POST)
 public BorrowDTO borrow(@RequestBody  BorrowDTO borrow ) {
    borrowerService.borrowBook(borrow);
    return borrow;
 }
}

编辑:我忘了提,我使用@RestController标注在我的控制器类。它包括自动@ResponseBody。

I forgot to mention that I use @RestController annotation on my controller class. It automatically includes @ResponseBody.

推荐答案

出于安全原因的一些浏览器不允许做出Ajax请求不在同一个起源。如果您想了解更多关于 CORS 我推荐的这个文章。您有几种选择来解决问题。

For security reasons some of the browsers don't allow to make ajax request that are not in the same origin. If you want read more on CORS I'm recommending this article. You have several choices to resolve your problem.

第一个是,如果你想保持你当前的项目结构,这两个项目
       到存在于不同的服务器。您应该启用 CORS (跨源资源共享)在服务器端支持,我看到你正在使用较新的 Spring框架所以你可以添加一个
   注释这将使 CORS 支持。注释为 @CrossOrigin 看的这个文章。

The first one is if you want to keep your current projects structure, both projects to exists on different servers. You should enable CORS (Cross origin resource sharing) support on server side and I see that you are using newer Spring Framework so you can just add one annotation that will enable CORS support. The annotation is @CrossOrigin see this article.

@RestController
@CrossOrigin(maxAge = 3600)
public class BookRestPostController {

 @RequestMapping(value = "/borrow", method=RequestMethod.POST)
 public BorrowDTO borrow(@RequestBody  BorrowDTO borrow ) {
    borrowerService.borrowBook(borrow);
    return borrow;
 }
}

如果您使用的是 Spring框架您可以在手动方式做旧版本 - 增加过滤器这将添加所需的响应头。请参见文章

If you are using older version of Spring Framework you can do in the manual way - add Filter which will add needed response headers. See this article

@Component
public class SimpleCORSFilter implements Filter {

    @Override
    public void init(FilterConfig arg0) throws ServletException {}

    @Override
    public void doFilter(ServletRequest req, ServletResponse resp,
            FilterChain chain) throws IOException, ServletException {
        // TODO Auto-generated method stub
        HttpServletResponse response=(HttpServletResponse) resp;

        response.setHeader("Access-Control-Allow-Origin", "*");
        response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE");
        response.setHeader("Access-Control-Max-Age", "3600");
        response.setHeader("Access-Control-Allow-Headers", "x-requested-with");

        chain.doFilter(req, resp);
    }

    @Override
    public void destroy() {}

}

这可能是实现你的目标最彻底的方法。
另外两个是创建服务器端代理,或者在一台服务器中部署客户端和服务器端code,但我的建议是不要使用代理服务器或同一服务器!

This is probably the cleanest way to achieve your goal. Other two alternatives are to create server side proxy or to deploy both client and server side code in one server but my suggestion is not use proxy or same server !.

通过简单的话,浏览器将preflight请求,它将,类型的一个额外的要求选项每个请求与特定的头文件(访问控制请求,方法和访问控制请求报头)。这些请求头会要求服务器的权限,使实际的请求。您的preflight响应需要,以使实际要求合作,承认这些头。

With simple words the browser will preflight request, it will send before every request, one extra request of type OPTIONS with specific headers (Access-Control-Request-Method and Access-Control-Request-Headers). These request headers will ask the server for permissions to make the actual request. Your preflight response needs to acknowledge these headers in order for the actual request to work.

这篇关于角JS和Spring MVC @RestController - POST状态0的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆