跨源请求阻止了Spring REST服务+ AJAX

[英]Cross-Origin Request Blocked Spring REST service + AJAX


Unable to call spring REST service

无法调用spring REST服务

My spring service

我的春天服务

@RequestMapping(value = "/MAS/authenticate", method = RequestMethod.POST)
public ResponseEntity<Map<String, String>> authenticate(@RequestBody Subject subject) {
    Map<String, String> result = new HashMap<String, String>();
    result.put("result_detail", "Invalid Password");
    result.put("result", "failure");
    HttpHeaders responseHeaders = new HttpHeaders();
    responseHeaders.setContentType(MediaType.APPLICATION_JSON);
    responseHeaders.add("Access-Control-Allow-Origin", "*"); // also added header to allow cross domain request for any domain
    return new ResponseEntity<Map<String, String>>(result, responseHeaders, HttpStatus.OK);
}

My AJAX code

我的AJAX代码

$.ajax(
{
  crossDomain: true,
  type: "POST",
  contentType: "application/json; charset=utf-8",
  async: false,
  url: "http://localhost:8080/SpringMVC/rest/MAS/authenticate",
  headers: {"Access-Control-Allow-Origin" : "*"},
  data:{},
  dataType: "json", //also tried "jsonp"
  success: function(data, status, jqXHR)
  {
    alert('success');
  },
  error: function(jqXHR, status)
  {
    alert('error');
  }
});

I am getting following error :(

我得到以下错误:

Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at http://localhost:8080/SpringMVC/rest/MAS/authenticate. This can be fixed by moving the resource to the same domain or enabling CORS.

跨源请求被阻止:相同的源策略不允许在http://localhost:8080/springmvc /rest/MAS/authenticate上读取远程资源。这可以通过将资源移动到相同的域或启用CORS来修复。

i have also tried dataType: "jsonp". its append my body object into URL which make different URL and cannot hit my service URL then and got 404 error.

我也尝试过数据类型:“jsonp”。它将我的body对象附加到URL中,URL产生了不同的URL,无法点击我的服务URL,并得到404错误。

My browser: firefox 36.0.4

我的浏览器,firefox 36.0.4

How i can get rid from this error, any help?

如何摆脱这个错误,有帮助吗?

3 个解决方案

#1


7  

My AJAX call and service were OK. After searching a lot on internet i have found that its server side problem not client side.

我的AJAX调用和服务没问题。在网上搜索了很多之后,我发现它的服务器端问题并不是客户端。

on server side with Spring we have to implement filter which will allow CORS requests.

在Spring的服务器端,我们必须实现允许CORS请求的过滤器。

filter will look like this.

滤镜是这样的。

import java.io.IOException;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.web.filter.OncePerRequestFilter;

public class CORSFilter extends OncePerRequestFilter {
    private static final Log LOG = LogFactory.getLog(CORSFilter.class);

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {

        response.addHeader("Access-Control-Allow-Origin", "*");
        if (request.getHeader("Access-Control-Request-Method") != null && "OPTIONS".equals(request.getMethod())) {
            LOG.trace("Sending Header....");
            // CORS "pre-flight" request
            response.addHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE");
            // response.addHeader("Access-Control-Allow-Headers", "Authorization");
            response.addHeader("Access-Control-Allow-Headers", "Content-Type");
            response.addHeader("Access-Control-Max-Age", "1");
        }
        filterChain.doFilter(request, response);
    }

}

and in web.xml apply this filter on your service requests like this

在网络。xml将此过滤器应用于您的服务请求,如下所示。

    <filter>
        <filter-name>cors</filter-name>
        <filter-class>com.test.common.controller.CORSFilter</filter-class> <!-- your package name and filter class -->
    </filter>
    <filter-mapping>
        <filter-name>cors</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping> 

This may help someone else who went through this problem. :)

这可能会帮助其他人解决这个问题。:)

#2


0  

By default the only method allowed is a GET, and you don't allow the POST on your server side:

默认情况下,唯一允许的方法是GET,并且不允许在服务器端发布:

Access-Control-Allow-Origin: *

This header only enables CORS, but you need to add this:

此标题仅支持CORS,但您需要添加以下内容:

Access-Control-Allow-Methods: POST, GET

More detailed how-to about the HTTP access control (CORS) on Mozilla project

关于Mozilla项目的HTTP访问控制(CORS)的详细说明。

So your code should be something like this:

所以你的代码应该是这样的:

responseHeaders.add("Access-Control-Allow-Methods", "POST, GET"); // also added header to allow POST, GET method to be available
responseHeaders.add("Access-Control-Allow-Origin", "*"); // also added header to allow cross domain request for any domain

Update:

更新:

I have re-read the article, and found out some details:

我重读了这篇文章,发现了一些细节:

A simple cross-site request is one that:

一个简单的跨站请求是:

  • Only uses GET, HEAD or POST. If POST is used to send data to the server, the Content-Type of the data sent to the server with the HTTP POST request is one of application/x-www-form-urlencoded, multipart/form-data, or text/plain.
  • 只使用GET、HEAD或POST。如果POST用于向服务器发送数据,则使用HTTP POST请求发送给服务器的内容类型为应用程序/x-www-form-urlencode、多部分/表单数据或文本/plain。
  • Does not set custom headers with the HTTP Request (such as X-Modified, etc.)
  • 不使用HTTP请求(如x修改等)设置自定义头部。

As you can read in bold, you must set other Content-Type for your data (currently it is contentType: "application/json; charset=utf-8",) or use the preflight technique described later:

正如您可以粗体阅读,您必须为您的数据设置其他内容类型(目前它是contentType:“application/json;或使用稍后描述的飞行前技术:

  • It uses methods other than GET, HEAD or POST. Also, if POST is used to send request data with a Content-Type other than application/x-www-form-urlencoded, multipart/form-data, or text/plain, e.g. if the POST request sends an XML payload to the server using application/xml or text/xml, then the request is preflighted.
  • 它使用的方法不是GET、HEAD或POST。另外,如果POST用于发送除application/ www-form- urlencodes、multipart/form-data或text/plain之外的内容类型的请求数据,例如,如果POST请求使用application/ XML或text/ XML向服务器发送XML有效负载,那么该请求是预先完成的。
  • It sets custom headers in the request (e.g. the request uses a header such as X-PINGOTHER)
  • 它在请求中设置自定义头(例如,请求使用一个头,如X-PINGOTHER)

So I suggest you either change the contentType or try to work with this header into your request:

因此,我建议您要么更改内容类型,要么尝试将此标题转换为您的请求:

Access-Control-Request-Headers: X-HEADER_NAME_OF_YOUR_CHOOSE

and this headers into your response:

你的回答是:

Access-Control-Allow-Methods: POST, GET, OPTIONS
Access-Control-Allow-Headers: X-HEADER_NAME_OF_YOUR_CHOOSE

And after that you can try to call your method.

然后你可以试着调用你的方法。

#3


0  

Following is the solution for cross platform spring boot web service call.

下面是跨平台spring引导web服务调用的解决方案。

Application URL: http://localhost:8080

应用程序的URL:http://localhost:8080

Webservice URL: http://localhost:9090

网络服务的URL:http://localhost:9090

In your spring controller use following annotation

在spring控制器中使用以下注释

@CrossOrigin(origins = "http://localhost:8080")
@RequestMapping(value = "/uri", method = RequestMethod.GET)
public SomeObject someMethod(){
// your logic will come here
}
智能推荐

注意!

本站翻译的文章,版权归属于本站,未经许可禁止转摘,转摘请注明本文地址:http://www.silva-art.net/blog/2015/04/01/415718b80ae36eff8061c6cf70c91441.html



 
© 2014-2019 ITdaan.com 粤ICP备14056181号  

赞助商广告