林'使用Angular HttpClient的新手(也写英文)
我遇到了问题,我尝试使用POST方法发送HTTP请求以便取消OAuth令牌请求,但是角度发送OPTIONS请求:
服务:
login(username: string, password: string) {
const body = `username=${encodeURIComponent(username)}&password=${encodeURIComponent(password)}&grant_type=password`;
const httpOptions = {
headers: new HttpHeaders({
'Content-Type': 'application/x-www-form-urlencoded',
'Authorization': 'Basic ' + btoa(TOKEN_AUTH_USERNAME + ':' + TOKEN_AUTH_PASSWORD)
})
};
return this.http.post<string>(AuthenticationService.AUTH_TOKEN, body, httpOptions);
结果:
对于我的后端,我使用的是Spring Security,并添加了一个过滤器以允许CORS:
@Bean
public FilterRegistrationBean corsFilter() {
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
CorsConfiguration config = new CorsConfiguration();
config.setAllowCredentials(true);
config.addAllowedOrigin("*");
config.addAllowedHeader("*");
config.addAllowedMethod("*");
source.registerCorsConfiguration("/**", config);
FilterRegistrationBean bean = new FilterRegistrationBean(new CorsFilter(source));
bean.setOrder(0);
return bean;
}
答案 0 :(得分:5)
它与角度无关,它是您的浏览器所做的。
我假设你的服务器运行在localhost:8080,而你的角度应用程序运行在localhost:4200。由于您的请求是跨源请求,因此浏览器首先发送OPTIONS
请求以查看它是否安全。此时,您的服务器返回一个带有http代码401的响应,该响应阻止发出请求。
您必须在服务器中进行一些配置,或者您可以使用webpack代理。这仅适用于您的本地计算机。如果您从服务器提供捆绑的角度应用程序,那么您将无需为生产做任何事情。我已经使用这种技术很长一段时间了,它工作得很好。
实施例,
用户从mydomain.com/ng-app访问我的角度应用程序 我也从同一个域mydomain.com/api
提供我的休息api因此,我的应用程序始终向服务器提出请求,从而导致生产中没有问题。
对于后者,您可以执行以下操作
在项目的根目录(proxy.conf.json
旁边)创建package.json
并将内容放在
{
"/api/": {
"target": "http://localhost:8080",
"secure": false,
"changeOrigin": true
}
}
在package.json中,修改您的start
脚本并将其设为ng serve --proxy-config proxy.conf.json
此外,从您的前端,不要直接将请求发送到localhost:8080,而只是编写类似http.post('/api/getSomeData')
的内容,它将向localhost:4200发出请求,将其重定向到localhost:8080。这样,您就不必处理CORS。
答案 1 :(得分:0)
对于spring boot应用程序,要启用cors请求,请在各自的控制器上使用@CrossOrigin(origins =“ *”,maxAge = 3600)。
答案 2 :(得分:0)
答案 3 :(得分:0)
对于NestJS / Express后端,我通过启用CORS来解决此问题:https://docs.nestjs.com/techniques/security#cors
答案 4 :(得分:-1)
由于OPTIONS
,CORS
请求首先被发送,Angular需要您的后端的许可才能知道它是否POST
。因此,在您的后端,您需要启用CORS
才能获得http请求。
答案 5 :(得分:-1)
最后我发现了错误。
过滤器的顺序不正确。我将它调整为Ordered.HIGHEST_PRECEDENCE
,这样它会覆盖Spring过滤器。
@Bean
public FilterRegistrationBean corsFilter() {
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
CorsConfiguration config = new CorsConfiguration();
config.setAllowCredentials(true);
config.addAllowedOrigin("*");
config.addAllowedHeader("*");
config.addAllowedMethod("*");
source.registerCorsConfiguration("/**", config);
FilterRegistrationBean bean = new FilterRegistrationBean(new CorsFilter(source));
bean.setOrder(Ordered.HIGHEST_PRECEDENCE);
return bean;
}