Angular 5 无法读取来自 Spring 应用程序的响应标头 [重复]

Posted

技术标签:

【中文标题】Angular 5 无法读取来自 Spring 应用程序的响应标头 [重复]【英文标题】:Angular 5 cannot read headers of response from Spring application [duplicate] 【发布时间】:2018-06-29 20:14:24 【问题描述】:

我在 Spring Boot 中编写 REST 服务,在 Angular 5 中编写客户端应用程序,成功登录后,Angular 应用程序无法按名称读取标题,但在 chrome 开发人员工具网络中我得到了所有标题:

Chrome 响应标头:

Access-Control-Allow-Credentials:true
Access-Control-Allow-Origin:http://localhost:4200
Authorization:Bearer eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiJhZG1pbi5hZG1pbkBnbWFpbC5jb20iLCJjcmVhdGVkIjoxNTE2NDc2MzMxNzIwLCJleHAiOjE1MTcwODExMzF9.pbytQyt1CywO2B8vo41ynhQ1VjzG9Wb-Bf-zpUkHNW9O4XWX4TD0A2PMyQJNlk-pCrgbxInHO67ibv4eAO8r0Q
Cache-Control:no-cache, no-store, max-age=0, must-revalidate
Content-Length:0
Date:Sat, 20 Jan 2018 19:25:41 GMT
Expires:0
Pragma:no-cache
Role:ADMIN
Vary:Origin
X-Application-Context:application:oracle:8091
X-Content-Type-Options:nosniff
X-Frame-Options:DENY
X-XSS-Protection:1; mode=block

但是当我尝试在控制台中打印它时,我没有得到这些标题。

public login(loginRequest: LoginRequest): Observable<Response> 
    return this.http.post(
      this.loginUrl,
      JSON.stringify(loginRequest),
       headers: this.headers 
    );
  

public login() 
    console.log(this.request);

    this.loginService.login(this.request)
      .subscribe(res => 
        if (res.status === 200) 
          console.log('Response: ', res);
          console.log('authorization: ', res.headers.get('Authorization'));
        
      , error => 
        if (error.status === 401) 
          console.log('Error');
        
      );
  

结果是:

Response:  
Response _body: "", status: 200, ok: true, statusText: "OK", headers: Headers, … 
headers: Headers
   headers: Map(3) "pragma" => Array(1), "cache-control" => Array(1), "expires" => Array(1)
   normalizedNames: Map(3) "pragma" => "pragma", "cache-control" => "cache-control", "expires" => "expires"
   __proto__: Object
   ok: true
   status: 200
   statusText: "OK"
   type: 2
   url: "http://localhost:8091/login"
   _body: ""

而且我不知道是谁的错,因此我还必须附加 Spring Security 配置:

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter 

    @Autowired
    private AuthenticationEntryPointImpl unauthorizedHandler;

    @Autowired
    private UserDetailsService userDetailsService;

    @Autowired
    private AuthenticationTokenFilter authenticationTokenFilter;

    @Autowired
    private BCryptPasswordEncoder passwordEncoder;

    @Autowired
    public void configureAuthentication(AuthenticationManagerBuilder authenticationManagerBuilder) throws Exception 
        authenticationManagerBuilder
                .userDetailsService(this.userDetailsService)
                .passwordEncoder(passwordEncoder);
    

    @Override
    protected void configure(HttpSecurity httpSecurity) throws Exception 
        httpSecurity
                .csrf().disable()
                .exceptionHandling().authenticationEntryPoint(unauthorizedHandler)
                .and()
                .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
                .and()
                .authorizeRequests()
                .antMatchers(
                        HttpMethod.POST,
                        "/register",
                        "/login"
                ).permitAll()
                .anyRequest().authenticated()
                .and().cors();

        httpSecurity.addFilterBefore(
                authenticationTokenFilter,
                UsernamePasswordAuthenticationFilter.class
        );

        httpSecurity
                .headers().cacheControl();
    

【问题讨论】:

我对 Angular JS 不太熟悉,但 this 答案和 @trichetriche 的答案可能对您的问题有所帮助。 对于服务器端配置,您必须将 CORS 映射配置为 this blog describe。 如果您仍然有设置 CORS 设置的问题,请注意您的授权服务器配置的 @Order。我强烈建议检查此github issue 并承诺实现它。 【参考方案1】:

您的问题是,当您的后端没有明确表示要公开它们时,angular 会隐藏所有标题。

这是通过在您的 cors 配置中添加一个新标头来完成的。如果我记得,标题是

Access-Control-Expose-Headers

并且您必须在此中将标题作为值提供,例如

Authorization,Content-type

我正在打电话,所以我不太愿意在网上寻找更多文档,抱歉

【讨论】:

谢谢。我在我的 REST 服务中添加了 exposedHeaders@CrossOrigin,现在它可以工作了!

以上是关于Angular 5 无法读取来自 Spring 应用程序的响应标头 [重复]的主要内容,如果未能解决你的问题,请参考以下文章

错误类型错误:无法读取tipo-struttura.component.ts(angular+spring+sql)未定义的属性“id”

Angular 5:错误类型错误:无法读取未定义的属性“偏移量”

Spring 5 MVC Angular 5 App投掷404错误

通过 Angular 5 和 Spring Sec 5 中的 HTTP GET 请求对用户进行身份验证

在 Angular => 错误中显示数据列表时出现此错误:TypeError:无法读取未定义的属性“0”

用于长时间运行过程的 Spring SSE