在Angular中调用我的REST服务时,没有响应标头。
Angular中的登录方法
login(username: string, password: string) {
const credentials = { "username": username, "password": password };
return this.http.post(this.url, credentials)
.subscribe(
data => console.log(data), // JSON.stringify(data.headers) also is empty
error => console.log(error)
);
}
Chrome开发者工具控制台中的输出
响应{_body:“”,状态:200,ok:true,statusText:“OK”,标题: 标题...}标题:Headers_headers:Map(0)_normalizedNames: 地图(0) proto :Objectok:truestatus:200statusText:“OK”类型:2url: “http://localhost:8080/backend/rest/login”_ body:“” proto :正文
但是当我向邮递员发送相同的帖子请求时,我得到了预期的结果:
Access-Control-Allow-Credentials →true
Access-Control-Allow-Origin →chrome-extension://fhbjgbiflinjbdggehcddcbncdddomop
Authorization →Bearer eyJ[...]
Connection →keep-alive
Content-Length →0
Date →Mon, 12 Jun 2017 13:19:54 GMT
Server →WildFly/10
Vary →Origin
X-Powered-By →Undertow/1
REST服务
@POST
@Consumes(MediaType.APPLICATION_JSON)
public Response authenticateUser(CredentialsDTO credentialsDTO) {
try {
authService.login(credentialsDTO.getUsername(), credentialsDTO.getPassword());
} catch (WrongCredentialsException e) {
return Response.status(Status.FORBIDDEN).entity("WrongCredentialsException").build();
}
// Issue token
String token = issueToken(credentialsDTO.getUsername());
// Return the token on the response
return Response.ok().header(AUTHORIZATION, "Bearer " + token).build();
}
为什么我看不到Chrome中的标题?
更新 我也在使用CORSFilter,它允许Javascript首先联系我的后端。这是我在web.xml中配置的方式
<filter>
<filter-name>CORS</filter-name>
<filter-class>com.thetransactioncompany.cors.CORSFilter</filter-class>
<init-param>
<param-name>cors.allowGenericHttpRequests</param-name>
<param-value>true</param-value>
</init-param>
<init-param>
<param-name>cors.allowOrigin</param-name>
<param-value>*</param-value>
</init-param>
<init-param>
<param-name>cors.allowSubdomains</param-name>
<param-value>false</param-value>
</init-param>
<init-param>
<param-name>cors.supportedMethods</param-name>
<param-value>GET, HEAD, POST, DELETE, OPTIONS</param-value>
</init-param>
<init-param>
<param-name>cors.supportedHeaders</param-name>
<param-value>*</param-value>
</init-param>
<init-param>
<param-name>cors.supportsCredentials</param-name>
<param-value>true</param-value>
</init-param>
<init-param>
<param-name>cors.maxAge</param-name>
<param-value>3600</param-value>
</init-param>
</filter>
<filter-mapping>
<!-- CORS Filter mapping -->
<filter-name>CORS</filter-name>
<url-pattern>*</url-pattern>
</filter-mapping>
虽然我认为它被配置为允许所有内容,但我不确定这是否与我的问题有关。
答案 0 :(得分:13)
默认情况下,CORS响应仅公开这6个标题:
Cache-Control
Content-Language
Content-Type
Expires
Last-Modified
Pragma
要允许脚本访问服务器发送的其他标头,服务器需要发送Access-Control-Expose-Headers
标头。
Access-Control-Expose-Headers响应标头通过列出其名称来指示哪些标头可以作为响应的一部分公开。
例如:Access-Control-Expose-Headers: Authorization, X-Foobar
您可以调整包含此文件的web.xml
文件,以允许从创建XHR的脚本访问Authorization
标题:
<init-param>
<param-name>cors.exposedHeaders</param-name>
<param-value>Authorization</param-value>
<init-param>
答案 1 :(得分:0)
我使用以下解决方案在Owin自托管Web API中允许我的自定义标头
using Owin;
using Microsoft.Owin.Cors;
using System.Threading.Tasks;
using System.Web.Cors;
namespace App.Web.App_Start
{
public static class CorsConfig
{
public static void Configure(IAppBuilder app)
{
var allowedOrigins = "comma,separated,list,of,origins";
var corsPolicy = new CorsPolicy
{
AllowAnyHeader = true,
AllowAnyMethod = true,
AllowAnyOrigin = false,
SupportsCredentials = true
};
corsPolicy.ExposedHeaders.Add("Custom-Header");
foreach (string origin in allowedOrigins.Split(','))
corsPolicy.Origins.Add(origin);
app.UseCors(new CorsOptions
{
PolicyProvider = new CorsPolicyProvider
{
PolicyResolver = context => Task.FromResult(corsPolicy)
}
});
}
}
}
我调用像这样的方法CorsConfig.Configure(app); //应用是Owin.IAppBuilder
答案 2 :(得分:0)
HttpResponse对象中的标头是延迟加载的,因此headers
在您强制加载值之前将显示为空。尝试调用response.headers.keys()
以查看所有可用的标头名称。顺便说一句,这还强制将所有值都加载到映射response.headers.headers
中。
如果只需要访问一个特定的标头值,请确保使用headers.get('my-header-name')
。