[英]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.快乐编码。
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.