简体   繁体   English

将本地 React 前端连接到本地 Spring Boot 中间件应用程序时出现 CORS 错误

[英]CORS error when connecting local React frontend to local Spring Boot middleware application

I am working on a frontend application in React that connects to a middleware service written in Spring boot.我正在 React 中开发一个前端应用程序,该应用程序连接到用 Spring Boot 编写的中间件服务。 I am attempting to call an endpoint from the front end as follows:我正在尝试从前端调用端点,如下所示:

return axios.post('http://localhost:8085/workshop/client/createClient', {username})
.then((response) => {
  console.log('Success')
})
.catch((error) => console.log(error));

Whenever I make the request in my browser I get the following errors:每当我在浏览器中发出请求时,都会出现以下错误:

OPTIONS http://localhost:8085/workshop/client/createClient 401 ()

Failed to load http://localhost:8085/workshop/client/createClient: Response for preflight has invalid HTTP status code 401.

As far as I understand, this is because the preflight request is being blocked by my middleware application.据我了解,这是因为我的中间件应用程序阻止了预检请求。 Having read a bit online about enabling this, I have added a CorsFilter to my spring boot application:在网上阅读了一些关于启用此功能的内容后,我在 Spring Boot 应用程序中添加了一个 CorsFilter:

@Slf4j
public class CORSFilter implements Filter {
  private static final String ONE_HOUR = "3600";

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

  @Override
  public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
    HttpServletResponse response = (HttpServletResponse) res;
    response.setHeader("Access-Control-Allow-Origin", "*");
    response.setHeader("Access-Control-Allow-Methods", "POST, PUT, GET, OPTIONS, DELETE");
    response.setHeader("Access-Control-Max-Age", ONE_HOUR);
    response.setHeader("Access-Control-Allow-Headers", "X-Requested-With,Origin,Content-Type, Accept, x-device-user-agent, Content-Type");

    if (req instanceof HttpServletRequest) {
       HttpServletRequest httpServletRequest = (HttpServletRequest) req;
       if (httpServletRequest.getHeader(HttpHeaders.ORIGIN) != null
          && httpServletRequest.getMethod().equals(HttpMethod.OPTIONS.name())
          && httpServletRequest.getHeader(HttpHeaders.ACCESS_CONTROL_REQUEST_METHOD) != null) {
          log.debug("Received an OPTIONS pre-flight request.");
          return;
       }
    }
    chain.doFilter(req, res);
  }

  @Override
  public void destroy() {
  }
}

And并且

@Configuration
public class MvcConfiguration {

 @Bean
 public FilterRegistrationBean corsFilter() {
   FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean();
   filterRegistrationBean.setFilter(new CORSFilter());
   filterRegistrationBean.addUrlPatterns("/*");
   filterRegistrationBean.setOrder(0);
   return filterRegistrationBean;
 }
}

Here is an example of the endpoint:这是端点的示例:

 @PostMapping("/createClient")
 public ResponseEntity<?> createClient(@RequestBody CreateClientDto clientDto) {
    try {
     ...
     return new ResponseEntity<>(responseBody, OK);
    } catch (Exception e ...) {}
  }

Any help would be greatly appreciated :)任何帮助将不胜感激:)

Update: I had the url slightly wrong for the request (hence the 404).更新:我的请求的 url 有点错误(因此是 404)。 I have updated the error message.我已经更新了错误信息。 I still seem to be having CORS issues.我似乎仍然有 CORS 问题。

These are the response headers that I can see in the dev tools:这些是我可以在开发工具中看到的响应标头:

Access-Control-Allow-Credentials:true
Access-Control-Allow-Headers:access-control-allow-credentials, access-control-allow-methods, access-control-allow-origin, allow, content-type
Access-Control-Allow-Methods:POST
Access-Control-Allow-Origin:http://localhost:3000
Allow:GET, HEAD, POST, PUT, DELETE, TRACE, OPTIONS, PATCH
Cache-Control:no-cache, no-store, max-age=0, must-revalidate
Content-Length:0
Date:Thu, 01 Mar 2018 14:06:38 GMT
Expires:0
Pragma:no-cache
Strict-Transport-Security:max-age=31536000 ; includeSubDomains
Vary:Origin
WWW-Authenticate:Basic realm="Spring"
X-Content-Type-Options:nosniff
X-Frame-Options:DENY
X-XSS-Protection:1; mode=block

And the request headers:和请求标头:

OPTIONS /workshop/client/createClient HTTP/1.1
Host: localhost:8085
Connection: keep-alive
Access-Control-Request-Method: POST
Origin: http://localhost:3000
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_3) 
AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.186 Safari/537.36
Access-Control-Request-Headers: access-control-allow-credentials,access-control-allow-methods,access-control-allow-origin,allow,content-type
Accept: */*
Accept-Encoding: gzip, deflate, br
Accept-Language: en-GB,en;q=0.9,en-US;q=0.8,da;q=0.7

I also had this issue, but allow me to give a straight forward answer in a simpler communication manner.我也有这个问题,但请允许我以更简单的沟通方式给出直接的答案。

First and foremost, you have to tell your server (Spring boot java), about the client (Reactjs ) URL .首先,你必须告诉你的服务器(Spring boot java),关于客户端(Reactjs) URL

For example, most of the times spring boot uses http://localhost:8080 and Reactjs uses http://localhost:3000 .例如,大多数时候 spring boot 使用http://localhost:8080而 Reactjs uses http://localhost:3000

So you have to navigate to the controller in Spring boot java and allow the URL of Reactjs to be given the permission for accessibility in the server (Spring boot).因此,您必须导航到 Spring boot java 中的控制器,并允许 Reactjs 的URL获得服务器中可访问性的权限(Spring boot)。 This will help you get rid of the CORS issue.这将帮助您摆脱CORS问题。

How do we do this in Spring boot?我们如何在 Spring Boot 中做到这一点? simply we add the @CrossOrigin annotation specifying the Reactjs URL link as below:只需添加@CrossOrigin注释,指定 Reactjs URL链接,如下所示:

For example :例如:

    @GetMapping("/orphans")
    @CrossOrigin(origins = "http://localhost:3000")
    Iterable<Student> read() {
        return studentService.findAll();
    }

The method above is to list all the orphans, so I gave Reactjs URL link permission then I got rid of the CORS issue.上面的方法是列出所有孤儿,所以我给了 Reactjs URL链接权限,然后我摆脱了CORS问题。

Happy coding.快乐编码。

Controller.java控制器.java

Refer to the below sample code to resolve this issue.请参阅以下示例代码来解决此问题。

@CrossOrigin(origins = "http://localhost:3000")
@RequestMapping(value="/sample", method = RequestMethod.GET, produces = "application/json")

public Student getStudent(){
}

This is a standard CORS issue, this basically means that user agent ie http://localhost:3000 doesn't have permissions to access resources at http://localhost:8085 .这是一个标准的 CORS 问题,这基本上意味着用户代理,即http://localhost:3000没有访问http://localhost:8085资源的权限。 You can learn more about it at https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS .您可以在https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS了解更多相关信息。

Your request headers should exactly map to server rules.您的请求标头应该完全映射到服务器规则。 Keeping any parameter as * won't work.将任何参数保留为*将不起作用。

For eg, if your request header has following:例如,如果您的请求标头具有以下内容:

Access-Control-Request-Method: POST
Access-Control-Request-Headers: <your custom headers>

Then, server rules show map your request header:然后,服务器规则显示映射您的请求标头:

Access-Control-Request-Method: GET, PUT, DELETE, POST
Access-Control-Request-Headers: <your custom headers>

Let me know if it helps!如果有帮助,请告诉我!

The issue seems to be resolved.问题似乎得到了解决。 I was missing the Accept request header (thanks @Anadi Sharma), and I also had the spring-boot-starter-security as a dependency, which seemed to be returning unauthorised.我错过了 Accept 请求标头(感谢@Anadi Sharma),而且我还将 spring-boot-starter-security 作为依赖项,它似乎未经授权返回。 I also didn't need the CorsFilter, in the end I just used the @CrossOrigin annotation on the endpoint.我也不需要 CorsFilter,最后我只是在端点上使用了 @CrossOrigin 注释。

add below line of code in fetch在 fetch 中添加下面的代码行

  export function getData(endpoint = '/', request = {}) {
    let url = endpoint;
    let req = Object.assign(
      {
        headers: {
          Accept: 'application/json',
          'Content-Type': 'application/json',
          'Access-Control-Allow-Origin': '*',
        },
      },
      request
    );
    console.log('url,req', url, req);
    return fetch(url, req).then(handleResponse).catch(handleErrors);
  }

And Add below line below Rest Controller class并在 Rest Controller 类下方添加以下行

@RestController
@CrossOrigin(origins = "*", allowedHeaders = "*")
class TestController{}

hope this would helpful :)希望这会有所帮助:)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 从 spring 引导应用程序连接到本地 MySQL 数据库时出错 - Error connecting to local MySQL database from spring boot application Spring 使用 Swing 本地 GUI 引导 Web 应用程序 - Spring Boot Web application with Swing Local GUI 在 Spring Boot 中连接到多个“动态”数据库以及本地“静态”数据库 - Connecting to Multiple "Dynamic" Databases Along With Local "Static" Database in Spring Boot 本地主机 Spring Boot 中的错误 404 - Error 404 in local host Spring Boot 使用Angular 7前端启动Spring-Boot应用程序时失败加载资源错误(缺少资源) - Failed to load resource error when starting Spring-Boot Application with Angular 7 Frontend (missing resources) 在对Spring Boot应用程序使用AJAX请求时,在Chrome中出现CORS错误 - Getting CORS error in Chrome when using AJAX requests to a Spring Boot application CORS 被阻止 - Spring 启动和反应 - CORS blocked - Spring Boot and React 如何解决 CORS 错误与 Oauth2 Spring 启动和反应 - How resolve CORS Error with Oauth2 Spring boot and react 将本地jar添加到Spring启动应用程序的pom.xml - Add local jar to pom.xml of Spring boot application Spring引导应用程序本地构建传递,但由于测试而在Jenkins中失败 - Spring boot application local build passes, but fails in Jenkins due to Tests
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM