从 API 响应读取响应标头 - Angular 5 + TypeScript
Posted
技术标签:
【中文标题】从 API 响应读取响应标头 - Angular 5 + TypeScript【英文标题】:Read response headers from API response - Angular 5 + TypeScript 【发布时间】:2018-06-19 10:15:54 【问题描述】:我正在触发一个HTTP
请求,并且我得到了有效的响应。该响应还有一个我希望阅读的标题X-Token
。我正在尝试下面的代码来读取标题,但是,结果我得到了 null
this.currentlyExecuting.request = this.http.request(reqParams.type, reqParams.url,
body: reqParams.body,
responseType: 'json',
observe: 'response'
).subscribe(
(_response: any) =>
// Also tried _response.headers.init();
const header = _response.headers.get('X-Token');
console.log(header);
onComplete(_response.body);
,
_error =>
onComplete(
code: -1,
message: Constants.WEBSERVICE_INTERNET_NOT_CONNNECTED
);
);
API
的响应在 Chrome 检查中检查时显示标头存在。
【问题讨论】:
您是否从服务器端公开了 x-token?使用“访问控制公开标头”。因为不是所有的头部都允许从客户端访问,你需要从服务器端公开它们。 如果他在控制台中有它,那么是的,他暴露了它。 @HrishikeshKale:你是对的。 Access-Control-Expose-Headers 工作。您可以将此作为答案发布。 我已将此作为答案发布。快乐编码:) 毛毛虫,我不同意。我有一种情况,我在服务器上添加标头并且可以在浏览器控制台中看到它,但浏览器代码看不到它。由于 CORS,我必须明确将其标记为(在我的服务器代码中)暴露给浏览器。 【参考方案1】:您是否使用access-control-expose-headers
从服务器端公开了X-Token
?因为不是所有的头部都允许从客户端访问,你需要从服务器端公开它们
同样在您的前端,您可以使用新的HTTP 模块来获得使用observe: 'response'
的完整响应
http
.get<any>('url', observe: 'response')
.subscribe(resp =>
console.log(resp.headers.get('X-Token'));
);
【讨论】:
post 方法是否也一样...我收到错误消息“在预检响应中 Access-Control-Allow-Headers 不允许请求标头字段观察。” 在哪里可以了解更多信息?这解决了我的问题,但我想知道发生了什么 @KaiCriticallyAcclaimedCooper 是的,这里肯定是链接html5rocks.com/en/tutorials/cors,还有 Github 问题github.com/angular/angular/issues/6583 我仍然有阅读标题的问题,我找到了答案,看到这个:***.com/questions/58601675/… 我可以在邮递员中看到标题。这是否意味着标题已暴露?当我使用上面的代码@HrishikeshKale 时,我没有得到那个标题【参考方案2】:在我的POST
响应中,我想要authorization header
,因为我有JWT Token
。
所以我从this 帖子中读到的是我想要的标题应该从后端添加为Expose Header
。
所以我所做的就是将Authorization
标头添加到我的Exposed Header 中,就像在我的filter class
中一样。
response.addHeader("Access-Control-Expose-Headers", "Authorization");
response.addHeader("Access-Control-Allow-Headers", "Authorization, X-PINGOTHER, Origin, X-Requested-With, Content-Type, Accept, X-Custom-header");
response.addHeader(HEADER_STRING, TOKEN_PREFIX + token); // HEADER_STRING == Authorization
在我的角度方面
在组件中。
this.authenticationService.login(this.f.email.value, this.f.password.value)
.pipe(first())
.subscribe(
(data: HttpResponse<any>) =>
console.log(data.headers.get('authorization'));
,
error =>
this.loading = false;
);
在我的服务端。
return this.http.post<any>(Constants.BASE_URL + 'login', username: username, password: password,
observe: 'response' as 'body')
.pipe(map(user =>
return user;
));
【讨论】:
【参考方案3】:您应该使用新的HttpClient
。 You can find more information here。
http
.get<any>('url', observe: 'response')
.subscribe(resp =>
console.log(resp.headers.get('X-Token'));
);
【讨论】:
【参考方案4】:正如 Hrishikesh Kale 所解释的,我们需要传递 Access-Control-Expose-Headers。
我们如何在 WebAPI/MVC 环境中做到这一点:
protected void Application_BeginRequest()
if (HttpContext.Current.Request.HttpMethod == "OPTIONS")
//These headers are handling the "pre-flight" OPTIONS call sent by the browser
HttpContext.Current.Response.AddHeader("Access-Control-Allow-Methods", "GET, POST, OPTIONS");
HttpContext.Current.Response.AddHeader("Access-Control-Allow-Headers", "*");
HttpContext.Current.Response.AddHeader("Access-Control-Allow-Credentials", "true");
HttpContext.Current.Response.AddHeader("Access-Control-Allow-Origin", "http://localhost:4200");
HttpContext.Current.Response.AddHeader("Access-Control-Expose-Headers", "TestHeaderToExpose");
HttpContext.Current.Response.End();
另一种方法是我们可以在 webApiconfig.cs 文件中添加如下代码。
config.EnableCors(new EnableCorsAttribute("", headers: "", methods: "*",exposedHeaders: "TestHeaderToExpose") SupportsCredentials = true );
**我们可以在 web.config 文件中添加自定义标头,如下所示。 *
<httpProtocol>
<customHeaders>
<add name="Access-Control-Expose-Headers" value="TestHeaderToExpose" />
</customHeaders>
</httpProtocol>
我们可以创建一个属性并使用该属性来装饰方法。
编码愉快!!
【讨论】:
【参考方案5】:您可以通过这种方式(Angular 6)从发布响应标头中获取数据:
import HttpClient, HttpHeaders, HttpResponse from '@angular/common/http';
const httpOptions =
headers: new HttpHeaders( 'Content-Type': 'application/json' ),
observe: 'response' as 'response'
;
this.http.post(link,body,httpOptions).subscribe((res: HttpResponse<any>) =>
console.log(res.headers.get('token-key-name'));
)
【讨论】:
【参考方案6】:您可以使用以下代码获取标题
let main_headers =
this.http.post(url,
email: this.username, password: this.password,
'headers' : new HttpHeaders ('Content-Type' : 'application/json'), 'responseType': 'text', observe:'response')
.subscribe(response =>
const keys = response.headers.keys();
let headers = keys.map(key =>
`$key: $response.headers.get(key)`
main_headers[key] = response.headers.get(key)
);
);
稍后我们可以从 json 对象中获取所需的标头。
header_list['X-Token']
【讨论】:
【参考方案7】:角度 7 服务:
this.http.post(environment.urlRest + '/my-operation',body, headers: headers, observe: 'response'); 组件:this.myService.myfunction().subscribe( (res: HttpResponse) => console.log(res.headers.get('x-token')); , 错误 => )
【讨论】:
【参考方案8】:试试这个简单的代码。
1.组件端代码: 获取 body 和 header 属性。这里在正文中有一个标记,在标题中有Authorization
。
loginUser()
this.userService.loginTest(this.loginCred).
subscribe(res =>
let output1 = res;
console.log(output1.body.token);
console.log(output1.headers.get('Authorization'));
)
2。服务端代码: 在正文中发送登录数据,并观察Observable
中任何组件端订阅的响应。
loginTest(loginCred: LoginParams): Observable<any>
const header1= 'Content-Type':'application/json',;
const body = JSON.stringify(loginCred);
return this.http.post<any>(this.baseURL+'signin',body,
headers: header1,
observe: 'response',
responseType: 'json'
);
【讨论】:
【参考方案9】:当从 ASP.NET Core 服务获取标头时,我必须执行以下操作才能让标头出现在 SPA Angular 应用程序中:
var builder = WebApplication.CreateBuilder(args);
services.AddCors(options =>
options.AddPolicy("MyExposeResponseHeadersPolicy",
builder =>
builder.WithOrigins("https://*.example.com")
.WithExposedHeaders("x-custom-header");
);
);
builder.Services.AddControllers();
var app = builder.Build();
【讨论】:
以上是关于从 API 响应读取响应标头 - Angular 5 + TypeScript的主要内容,如果未能解决你的问题,请参考以下文章
无法使用 cors 从 angular 2 获取所有响应标头
Angular 5 无法读取来自 Spring 应用程序的响应标头 [重复]
在 Angular 5 应用程序中响应 Spring Boot 时无法读取授权标头
从跨域 http.get 请求的 ASP.NET Web API 2 响应中获取 Angular 中的特定响应标头(例如 Content-Disposition)