英文:
Java Spring controler refuses all requests expect GET
问题
我正在开发使用Java Spring框架构建的应用程序,前端使用Angular,但我遇到了一个问题,没有您的帮助我无法解决。当我从Angular发起请求到Java时,只有GET请求是成功的,但是POST、DELETE和PUT请求返回以下错误:
跨源资源共享(CORS)策略阻止了从源 'http://localhost:4200' 发起的 XMLHttpRequest 到 'http://localhost:8080/patient' 的请求。所请求的资源上没有 'Access-Control-Allow-Origin' 头部。
控制器
@Controller
@RequestMapping("/patient")
@CrossOrigin(origins = "*", maxAge = 3600)
public class PatientController {
private PatientService patientService;
@Autowired
public PatientController(PatientService patientService) {
this.patientService = patientService;
}
@GetMapping
public ResponseEntity<Iterable<Patient>> getPatient() {
return new ResponseEntity<>(patientService.findAll(), HttpStatus.OK);
}
@PostMapping
public ResponseEntity<Iterable<Patient>> postPatient() {
return new ResponseEntity<>(patientService.findAll(), HttpStatus.OK);
}
@PutMapping
public ResponseEntity<Iterable<Patient>> putPatient() {
return new ResponseEntity<>(patientService.findAll(), HttpStatus.OK);
}
@DeleteMapping
public ResponseEntity<Iterable<Patient>> deletePatient() {
return new ResponseEntity<>(patientService.findAll(), HttpStatus.OK);
}
}
Angular 服务
getPatients() {
this.http.post(AppComponent.apiUrl + '/patient', this.httpOptions)
.subscribe(data => {
console.log(data);
});
}
proxy.conf.json
{
"/api*": {
"target": "http://localhost:8080",
"secure": false,
"logLevel": "debug",
"changeOrigin": true
}
}
提前感谢您的帮助!
英文:
I am working on Java Spring application with frontend on Angular but I faced issue that I can't resolve without yours help. When I am making requests from Angular to Java only GET ones are passing but POST, DELETE and POST return following error
>Access to XMLHttpRequest at 'http://localhost:8080/patient' from origin 'http://localhost:4200' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
Controler
@Controller
@RequestMapping("/patient")
@CrossOrigin(origins = "*", maxAge = 3600)
public class PatientController {
private PatientService patientService;
@Autowired
public PatientController(PatientService patientService) {
this.patientService = patientService;
}
@GetMapping
public ResponseEntity<Iterable<Patient>> getPatient() {
return new ResponseEntity<>(patientService.findAll(), HttpStatus.OK);
}
@PostMapping
public ResponseEntity<Iterable<Patient>> postPatient() {
return new ResponseEntity<>(patientService.findAll(), HttpStatus.OK);
}
@PutMapping
public ResponseEntity<Iterable<Patient>> putPatient() {
return new ResponseEntity<>(patientService.findAll(), HttpStatus.OK);
}
@DeleteMapping
public ResponseEntity<Iterable<Patient>> deletePatient() {
return new ResponseEntity<>(patientService.findAll(), HttpStatus.OK);
}
}
Angular service
getPatients() {
this.http.post(AppComponent.apiUrl + '/patient', this.httpOptions)
.subscribe(data => {
console.log(data);
});
}
proxy.conf.json
{ "/api*": {
"target":"http://localhost:8080",
"secure":false,
"logLevel":"debug",
"changeOrigin": true
}
}
Thank you in advance!
答案1
得分: 0
不需要在 @CrossOrigin
注解中设置 origins=*
,默认情况下允许所有来源。
你尝试将注解放在方法级别吗?
英文:
Not need to set origins=*
in @CrossOrigin
annotation, by default all origins are permited.
You tried to put the annotation at method level?
答案2
得分: 0
您可以尝试这样做:
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
@EnableWebMvc
public class CorsConfig implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedOrigins("https://localhost:4200")
.allowCredentials(true);
}
}
并确保您的Angular客户端发送其凭据:
httpOptions = {
withCredentials: true,
...
}
<details>
<summary>英文:</summary>
You could try this:
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
@EnableWebMvc
public class CorsConfig implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedOrigins("https://localhost:4200")
.allowCredentials(true);
}
}
And make sure that your angular client sends his credentials:
httpOptions = {
withCredentials: true,
...
}
</details>
# 答案3
**得分**: 0
Well, I resolved the issue.
I don't know why but CORS Filter, which is a quite popular resolution for issues like that, didn't change anything, neither did the proxy config. However, adding a CorsConfigurationSource bean and the following lines to the `configure` method resolved the problem.
**SecurityConfig.java**
```java
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
//Controlling access
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
...
.and()
.cors();
}
@Bean
CorsConfigurationSource corsConfigurationSource() {
CorsConfiguration configuration = new CorsConfiguration();
configuration.setAllowedOrigins(Collections.singletonList("*"));
configuration.setAllowedMethods(Collections.singletonList("*"));
configuration.setAllowedHeaders(Collections.singletonList("*"));
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", configuration);
return source;
}
}
Another solution that worked for me was adding the following class:
@Configuration
public class WebConfiguration implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry
.addMapping("/**")
.allowedMethods("*")
.allowedHeaders("*")
.allowedOrigins("*")
.allowCredentials(false);
}
}
But in this solution, it is also essential to add .and().cors()
lines into the security config.
英文:
Well, I resolved the issue.
I don't know why but CORS Fitler that is quite popular resolution for issues like that doesn't changed anything neiher the proxy config but adding CorsConfigurationSource bean and following lines to configure
method resolved the problem.
SecurityConfig.java
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
//Controlling access
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
...
.and()
.cors()
}
@Bean
CorsConfigurationSource corsConfigurationSource() {
CorsConfiguration configuration = new CorsConfiguration();
configuration.setAllowedOrigins(Collections.singletonList("*"));
configuration.setAllowedMethods(Collections.singletonList("*"));
configuration.setAllowedHeaders(Collections.singletonList("*"));
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", configuration);
return source;
}
}
Also the second one which was working for me was to add a following class:
@Configuration
public class WebConfiguration implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry
.addMapping("/**")
.allowedMethods("*")
.allowedHeaders("*")
.allowedOrigins("*")
.allowCredentials(false);
}
}
But in this solution is also essential to add .and().cors()
lines into security config.
答案4
得分: 0
这是一个非常烦人的 Angular 配置。仅允许跨源是不够的。您还需要允许一些方法和一些头部信息。这个配置对我很有帮助:
@Configuration
@EnableWebMvc
public class WebConfig implements WebMvcConfigurer {
@Value("${angular}")
private String angularOrigin;
@Bean
public WebMvcConfigurer corsConfigurer(){
return new WebMvcConfigurer() {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry
.addMapping("/**")
.allowedOrigins(angularOrigin)
.allowedHeaders("Authorization", "Cache-Control", "Content-Type", "Accept", "X-Requested-With", "Access-Control-Allow-Origin", "Access-Control-Allow-Headers", "Origin")
.exposedHeaders("Access-Control-Expose-Headers", "Authorization", "Cache-Control", "Content-Type", "Access-Control-Allow-Origin", "Access-Control-Allow-Headers", "Origin")
.allowedMethods("PUT","GET","POST","DELETE","OPTIONS");
}
};
}
}
同时注意应该允许 OPTION HTTP 方法。
英文:
This is a very annoying configuration of Angular. Just allowing cross origins wouldn't be enough. You also would need to allow methods and some headers. This configuration helped me:
@Configuration
@EnableWebMvc
public class WebConfig implements WebMvcConfigurer {
@Value("${angular}")
private String angularOrigin;
@Bean
public WebMvcConfigurer corsConfigurer(){
return new WebMvcConfigurer() {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry
.addMapping("/**")
.allowedOrigins(angularOrigin)
.allowedHeaders("Authorization", "Cache-Control", "Content-Type", "Accept", "X-Requested-With", "Access-Control-Allow-Origin", "Access-Control-Allow-Headers", "Origin")
.exposedHeaders("Access-Control-Expose-Headers", "Authorization", "Cache-Control", "Content-Type", "Access-Control-Allow-Origin", "Access-Control-Allow-Headers", "Origin")
.allowedMethods("PUT","GET","POST","DELETE","OPTIONS");
}
};
}
}
Also notice that there is an OPTION HTTP method that should be allowed.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论