[英]Adding any options or headers on the Angular 2 http.post sends OPTIONS
我正在尝试通过http.post()
将令牌信息发送回服务器。 如果我从中删除选项,它将发送POST,但如果将其重新添加,则会发送从服务器代码中拒绝的OPTIONS。 我也尝试删除“ withCredentials”。
export class EntityService {
public entity: EntityModel;
private options: RequestOptions;
constructor( @Inject(Http) private http: Http, @Inject(AuthenticationService) authService) {
let headers = new Headers({ 'X-Authorization': 'Bearer ' + authService.token});
this.options = new RequestOptions({ headers: headers, withCredentials: true });
}
public store(entity: EntityModel): Observable<string> {
var request;
if (!entity.uuid) {
request = this.http.post("http://localhost:8080/api/entity", JSON.stringify(entity), this.options);
}
else {
request = this.http.put("http://localhost:8080/api/entity", JSON.stringify(fact), this.options);
}
return request.map((res: Response) => res.text());
}
}
我的身份验证服务如下所示:
import { Injectable, Inject } from '@angular/core';
import { Http, Headers, Response } from '@angular/http';
import { Observable } from 'rxjs';
import 'rxjs/add/operator/map'
//http://jasonwatmore.com/post/2016/08/16/angular-2-jwt-authentication-example-tutorial
@Injectable()
export class AuthenticationService {
public token: string;
constructor(@Inject(Http) private http: Http) {
// set token if saved in local storage
var currentUser = JSON.parse(localStorage.getItem('currentUser'));
this.token = currentUser && currentUser.token;
}
login(username: string, password: string): Observable<boolean> {;
console.log("login...");
return this.http.post('http://localhost:8080/api/auth/login', JSON.stringify({ username: username, password: password }))
.map((response: Response) => {
// login successful if there's a jwt token in the response
let token = response.json() && response.json().token;
if (token) {
// set token property
this.token = token;
// store username and jwt token in local storage to keep user logged in between page refreshes
localStorage.setItem('currentUser', JSON.stringify({ username: username, token: token }));
// return true to indicate successful login
return true;
} else {
// return false to indicate failed login
return false;
}
});
}
logout(): void {
// clear token remove user from local storage to log user out
this.token = null;
localStorage.removeItem('currentUser');
}
}
这是我的Spring配置:
@SpringBootApplication
public class SpringBootApp extends WebMvcConfigurerAdapter {
private boolean workOffline = true;
private boolean setupSchema = false;
private IGraphService graphService;
private DbC conf;
@Autowired
public SpringBootApp(IGraphService graphService, DbC conf)
{
this.graphService = graphService;
this.conf = conf;
}
public static void main(String[] args) throws Exception {
SpringApplication.run(SpringBootApp.class, args);
}
@Bean
public Filter caseInsensitiveRequestFilter() {
return new CaseInsensitiveRequestFilter();
}
@Override
public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
configurer.enable();
}
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedOrigins("http://localhost:3000")
.allowedMethods("GET", "PUT", "POST", "DELETE","OPTIONS");
}
@Bean
public FilterRegistrationBean corsFilter() {
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
CorsConfiguration config = new CorsConfiguration();
config.setAllowCredentials(true);
config.addAllowedOrigin("http://localhost:3000");
config.addAllowedHeader("*");
config.addAllowedMethod("*");
source.registerCorsConfiguration("/**", config);
FilterRegistrationBean bean = new FilterRegistrationBean(new CorsFilter(source));
bean.setOrder(0);
return bean;
}
}
我真的不知道该怎么办,因为我正在跟踪在请求http.GET时发送的Angular2 OPTIONS方法中所说的内容 ,这不是预检请求。 之前我曾因内容类型错误而遇到此问题。
OPTIONS
请求仅由浏览器发出。 Angular根本不涉及。
“而且这不是飞行前的要求。” -当然是。
您需要配置服务器以正确响应OPTIONS
请求,或确保从与请求相同的服务器(也是同一端口)加载Angular应用程序。
实际的修复有两个原因:不正确的CORS实施-请在此处查看更多信息: Spring 4/5全局CORS配置无法正常工作,因为在请求的请求中没有'Access-Control-Allow-Origin'标头资源`
然后,当我在登录后进行发布时,出现错误415 Unsupported Media Type
。 按照此处的说明进行操作后: POST JSON失败,显示415不支持的媒体类型,Spring 3 mvc
我在请求中添加了Content-Type
和Accept
标头,它解决了该问题。 似乎Content-Type
是实际需要的。
export class EntityService {
public entity: EntityModel;
private options: RequestOptions;
constructor( @Inject(Http) private http: Http, @Inject(AuthenticationService) authService) {
let headers = new Headers({
'X-Authorization': 'Bearer ' + authService.token,
'Content-Type': 'application/json'
});
this.options = new RequestOptions({ headers: headers, withCredentials: true });
}
public store(entity: EntityModel): Observable<string> {
var request;
if (!entity.uuid) {
request = this.http.post("http://localhost:8080/api/entity", JSON.stringify(entity), this.options);
}
else {
request = this.http.put("http://localhost:8080/api/entity", JSON.stringify(fact), this.options);
}
return request.map((res: Response) => res.text());
}
}
像这样使用http发布
import { Http, Headers, Response, Request } from '@angular/http';
let headers = new Headers();
headers.append('Content-Type', 'application/json');
headers.append('X-Authorization', this.token);
headers.append('Authorization', 'Bearer ' + jwtToken);
return this.http.post(url, data, {headers})
.map(res => { console.log(res) })
.catch(err => { console.log(err) } );
请注意,此示例返回您可以订阅的Observable。 也是我的例子
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.