在 Angular 2 http.post 上添加任何选项或标头都会发送选项



我正在尝试通过http.post()将令牌信息发送回服务器。如果我从中删除选项,它会发送一个 POST,但如果我将它们重新添加回去,它会发送从服务器代码中被拒绝的选项。我也尝试删除"带有凭据"。

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');
    }
}

这是我的弹簧配置:

@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 时发送的 Angular2 OPTIONS 方法中所说的内容。GET,这不是预检请求。我之前遇到过这个问题,内容类型错误。

OPTIONS请求仅由浏览器发出。Angular 根本不参与。

"这不是飞行前的请求。">

您需要配置服务器以正确响应OPTIONS请求,或者确保 Angular 应用程序从您发出请求的同一服务器(也是同一端口(加载。

实际修复是由于两个原因: 不正确的 CORS 实现 - 有关更多信息,请查看此处:Spring 4/5 全局 CORS 配置不起作用,给出"请求的资源上不存在'访问控制-允许源'标头">

然后,当我在登录后开机自检时,我收到错误415 Unsupported Media Type.按照此处的说明操作后:POST JSON 失败,并显示 415 不支持的媒体类型,Spring 3 mvc

我在请求中添加了Content-TypeAccept标头,它解决了问题。似乎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) } );

请注意,此示例返回您可以订阅的可观察量。还有我的例子

相关内容

最新更新