In case of CORS requests, browsers can only access the following response headers by default:
对于CORS请求,默认情况下,浏览器只能访问以下响应头部:
- Cache-Control
- Content-Language
- Content-Type
- Expires
- Last-Modified
- Pragma
If you would like your client app to be able to access other headers, you need to set the Access-Control-Expose-Headers header on the server:
如果希望您的客户端应用程序能够访问其他标头,则需要在服务器上设置Access-Control-Expose-Headers标头:
Access-Control-Expose-Headers: Access-Token, Uid
This really helped me, thanks Nick Uraltsev for your answer.
这对我真的很有帮助,谢谢尼克·乌拉尔采夫的回答。
For those of you using nodejs with cors:
对于那些在CORS中使用NodeJS的用户:
...
const cors = require('cors');
const corsOptions = {
exposedHeaders: 'Authorization',
};
app.use(cors(corsOptions));
...
In the case you are sending the response in the way of res.header('Authorization', `Bearer ${token}`).send();
如果您是以res.Header(‘Authorization’,`承载${Token}`)的方式发送响应,.Send();
I was facing the same problem. I did this in my WebSecurity.java
, it's about the setExposedHeaders
method in the CORS configuration.
我也面临着同样的问题。这是在我的WebSecurity.java中完成的,它是关于CORS配置中的setExposedHeaders方法的。
@Bean
CorsConfigurationSource corsConfigurationSource() {
CorsConfiguration configuration = new CorsConfiguration();
configuration.setAllowCredentials(true);
configuration.setAllowedOrigins(Arrays.asList(FRONT_END_SERVER));
configuration.setAllowedMethods(Arrays.asList("GET", "POST", "PUT", "DELETE"));
configuration.setAllowedHeaders(Arrays.asList("X-Requested-With","Origin","Content-Type","Accept","Authorization"));
// This allow us to expose the headers
configuration.setExposedHeaders(Arrays.asList("Access-Control-Allow-Headers", "Authorization, x-xsrf-token, Access-Control-Allow-Headers, Origin, Accept, X-Requested-With, " +
"Content-Type, Access-Control-Request-Method, Access-Control-Request-Headers"));
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", configuration);
return source;
}
I hope it works.
我希望它能起作用。
Faced same problem in asp.net core
Hope this helps
在ASP.NET核心中面临同样的问题希望这能有所帮助
public static class CorsConfig
{
public static void AddCorsConfig(this IServiceCollection services)
{
services.AddCors(options =>
{
options.AddPolicy("CorsPolicy",
builder => builder
.WithExposedHeaders("X-Pagination")
);
});
}
}
According to official docs:
根据官方文件:
This may help if you want the HTTP headers that the server responded with. All header names are lower cased and can be accessed using the bracket notation. Example: response.headers['content-type']
will give something like: headers: {},
如果您需要服务器用来响应的HTTP头,这可能会有所帮助。所有标头名称都是小写的,可以使用方括号表示法访问。示例:Response.Headers[‘Content-type’]将提供如下内容:Headers:{},
There is one more hint that not in this conversation.
for asp.net core 3.1
first add the key that you need to put it in the header, something like this:
还有一个暗示不是在这次对话中。对于ASP.NET core 3.1,首先添加将其放入标题中所需的键,如下所示:
Response.Headers.Add("your-key-to-use-it-axios", "your-value");
where you define the cors policy (normaly is in Startup.cs
) you should add this key to WithExposedHeaders like this.
在您定义CORS策略的地方(Normy在Startup.cs中),您应该将这个键添加到WithExposedHeaders,如下所示。
services.AddCors(options =>
{
options.AddPolicy("CorsPolicy",
builder => builder
.AllowAnyHeader()
.AllowAnyMethod()
.AllowAnyOrigin()
.WithExposedHeaders("your-key-to-use-it-axios"));
});
}
you can add all the keys here.
now in your client side you can easily access to the your-key-to-use-it-axios by using the response result.
你可以在这里添加所有的钥匙。现在,在您的客户端,您可以通过使用响应结果轻松地访问Your-key-to-use-it-axios。
localStorage.setItem("your-key", response.headers["your-key-to-use-it-axios"]);
you can after use it in all the client side by accessing to it like this:
在所有客户端使用后,您可以通过如下方式访问它:
const jwt = localStorage.getItem("your-key")
In axios CORS requests, browsers can access only few headers by default.
在axios CORS请求中,默认情况下,浏览器只能访问少数标头。
But if you need to access a custom header from response, you have to send response with Access-Control-Expose-Headers
form your backend server.
但是,如果您需要从Response访问自定义头,则必须从后端服务器发送带有Access-Control-Exposure-Header的响应。
Hare is a example for Nodejs backend and Reactjs front end:
Hare是NodeJS后端和Reactjs前端的示例:
res.header('Access-Control-Expose-Headers', 'x-xsrf-token');
return res.header("x-xsrf-token", token).status(200)
.send({
id: user.id,
email: user.email,
});
res.header('Access-Control-Expose-Headers', 'x-xsrf-token');
Res.Header(‘Access-Control-Exposed-Headers’,‘x-xsrf-Token’);
for this line I can log my custom header like
对于此行,我可以记录我的自定义标题,如下所示
axios.post("/login", {
email: emailInput.current.value,
password: passwordInput.current.value,
})
.then(function (response) {
console.log(response.headers["x-xsrf-token"]);
});
Without Access-Control-Expose-Headers
in your response you will get undefine in console log. Check your response header in network tab that it contains the header with your custom name with it.
如果您的响应中没有Access-Control-Expose-Header,您将在控制台日志中得到未定义。检查网络选项卡中的响应标头是否包含带有您的自定义名称的标头。
Custom HTTP headers can not be accessed on client-side due to CORS restrictions. You need to add Access-Control-Expose-Headers setting on the server-side.
由于CORS限制,客户端无法访问自定义的HTTP头。您需要在服务器端添加Access-Control-Expose-Headers设置。
What are Access-Control-Expose-Headers?
Please go to https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Expose-Headers
什么是Access-Control-Expose-Header?请访问https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Expose-Headers
By default only these HTTP headers are exposed:
默认情况下,仅公开以下HTTP标头:
- Cache-Control
- Content-Language
- Content-Length
- Content-Type
- Expires
- Last-Modified
- Pragma
For custom HTTP headers, you need to customize Access-Control-Expose-Headers in response headers.
对于自定义的HTTP报头,您需要在响应报头中自定义Access-Control-Exposure-Header。
If you are using Django on the server side you can use django-cors-headers
(https://pypi.org/project/django-cors-headers/) for CORS settings management.
如果您在服务器端使用django,您可以使用django-cors-Headers(https://pypi.org/project/django-cors-headers/)来管理CORS设置。
For example, with django-cors-headers
you can add a list of HTTP headers that are to be exposed to the browser by CORS_ALLOW_HEADERS
setting
例如,使用Django-CORS-Headers,您可以通过CORS_ALLOW_HEADERS设置添加要向浏览器公开的HTTP标头列表
from corsheaders.defaults import default_headers
CORS_ALLOW_HEADERS = list(default_headers) + [
'my-custom-header',
]
In case you're using Laravel 8 for the back-end side with CORS properly configured, add this line to config/cors.php
:
如果您使用的后端为Laravel 8,并正确配置了CORS,请将以下行添加到CONFIG/cors.php:
'exposed_headers' => ['Authorization'],
‘exposed_Headers’=>[‘授权’],
For the SpringBoot2 just add
对于SpringBoot2,只需添加
httpResponse.setHeader("Access-Control-Expose-Headers", "custom-header1, custom-header2");
to your CORS filter implementation code to have whitelisted custom-header1
and custom-header2
etc
到您的CORS筛选器实现代码,以具有白名单中的Custom-Header1和Customer-Header2等
try like this
试着这样做
.then(res =>{
console.log(res);
console.log(res.headers['x-total-count']);
setTotalRecords(res.headers['x-total-count']);
setTableData(res.data);
});
for django help
对于Django的帮助
CORS_EXPOSE_HEADERS = [
'your header'
]
For Spring Boot 2 if you don't want to use global CORS configuration, you can do it by method or class/controller level using @CrossOrigin
adnotation with exposedHeaders
atribute.
对于Spring Boot2,如果您不想使用全局CORS配置,则可以通过方法或类/控制器级别使用带有exposedHeaders属性的@CrossOrigin注释来实现。
For example, to add header authorization
for YourController
methods:
例如,要为YourController方法添加标头授权:
@CrossOrigin(exposedHeaders = "authorization")
@RestController
public class YourController {
...
}
If you are using Django without django-cors-headers, you can write custom middleware.
如果您正在使用没有Django-cors-Header的Django,您可以编写定制的中间件。
class CustomCorsMiddleware:
def __init__(self, get_response):
self.get_response = get_response
def __call__(self, request):
response['Access-Control-Expose-Headers'] = 'MY-HEADER, ANOTHER-HEADER'
return response
You can also set other CORS heades here.
您还可以在此处设置其他CORS标题。
Then you should register your middleware by inserting it at the beggining of the MIDDLEWARE
list in your project's settings.py
file.
然后,您应该通过在项目的settings.py文件中中间件列表的乞求处插入中间件来注册您的中间件。
MIDDLEWARE = [
'myapp.middleware.CustomCorsMiddleware',
...
]
Below the list of clear steps to make sure you don't need to spend the whole evening googling as I did. I address the matter of how to read the Authorization header in the axios response (!).
下面列出了一些明确的步骤,以确保你不需要像我一样花整个晚上去谷歌。我解决了如何读取AXIOS响应(!)中的Authorization标头的问题。
For the back-end I am using standard ExpressJS. I am using: cors()
and helmet()
middleware in Express with the empty configuration but the below works nonetheless.
对于后端,我使用标准的ExpressJS。我在Express中使用了具有空配置的:CORS()和helmet()中间件,但是下面的配置仍然可以工作。
- Make sure your backend sends
Access-Control-Expose-Headers
. At the begining set it to *
to eliminate other possibilities. In Express, this going to be:
res.setHeader('Access-Control-Expose-Headers', '*')
- Make sure your backend sends
Access-Control-Allow-Headers
. Don't confuse with the 1st. step as both sound similar. Set this to cover all the headers you want to read from. In my case:
res.setHeader('Access-Control-Allow-Headers', 'Authorization,x-client-session')
- In your front-end app, Axios will return "AxiosHeaders" type for the headers. You should have your headers exposed now. Specifically for Authorization use:
const res = await axios(init)
const authHeader = res.headers.getAuthorization()
Even in the most up to date package version you may get TypeScript error that: This expression is not callable but it is.
即使是在最新的包版本中,您也可能会收到以下类型的脚本错误:此表达式不可调用,但它可以调用。
This is it.
就是这个。
[expanding on what @vladimir said]
[扩大@弗拉基米尔所说的内容]
if you're using Django
and django-cors-headers
to allow/control CORS,
you should set the following, in your settings.py
如果您使用django和django-cors-Header来允许/控制CORS,则应该在settings.py中设置以下内容
CORS_EXPOSE_HEADERS = ['yourCustomHeader']
If you are working with Spring Boot 3 and Spring Security 6 or up, this could work:
如果您使用的是Spring Boot 3和Spring Security 6或更高版本,这可能会起作用:
In your @Configuration class includes this:
在@Configuration类中包含以下内容:
@Bean
public CorsFilter corsFilter() {
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
CorsConfiguration config = new CorsConfiguration();
config.addAllowedOrigin("*");
config.addAllowedMethod("*");
//Allow several headers
config.addAllowedHeader("Authorization");
config.addAllowedHeader("X-Custom-Header");
config.addAllowedHeader("Another-Header");
// Expose custom headers
config.addExposedHeader("Authorization");
config.addExposedHeader("X-Custom-Header");
config.addExposedHeader("Another-Header");
source.registerCorsConfiguration("/**", config);
return new CorsFilter(source);
}
Be careful cause the previous configuration is so general.
请小心,因为前面的配置非常通用。
更多回答
My bad I forgot to expose that fields.
我的错是我忘了暴露那些区域。
If you are using Rails with Rack-Cors you need to set expose: ['Access-Token', 'Uid']
on the origin like: resource '*', :headers => :any, :methods => [:get, :post, :put, :patch, :delete, :options, :head], expose: ['Access-Token', 'Uid']
如果将Rails与机架核心一起使用,则需要在源服务器上设置Expose:[‘Access-Token’,‘Uid’],如下所示:resource‘*’,:Header=>:Any,:Methods=>[:Get,:Post,:Put,:Patch,:Delete,:Options,:Head],Expose:[‘Access-Token’,‘UID’]
I don't get it. If they are not exposed, why are the additional headers visible in the browser but not in the axios response?
我还是不明白。如果它们没有公开,为什么附加的标头在浏览器中可见,但在AXIOS响应中不可见?
@adanilev, browsers allow you to see them for debugging purposes, but prevent you from accessing them through APIs for security reasons. It prevents clients from getting secured credentials from servers, allowing the server to determine what access a client has. TLDR: it's done on purpose for security
@adanilev,浏览器允许您出于调试目的查看它们,但出于安全原因,您无法通过API访问它们。它防止客户端从服务器获取安全凭据,从而允许服务器确定客户端拥有什么访问权限。TLDR:这是为了安全而故意这样做的
I have this in my NGINX confg file... 'Access-Control-Expose-Headers' 'Authorization, X-Suggested-Filename, content-disposition' always;
Still only see content-type: "application/pdf"
really need to pull content-disposition
我的恩吉克斯档案里有这个。‘Access-Control-Exposed-Headers’‘授权,X-建议的文件名,Content-Disposal’;仍然只看到Content-type:“Application/pdf”确实需要拉出Content-Disposal
For those wondering, you could pass an array here too: exposedHeaders: ['Authorization','X-Total-Count']
对于那些想知道的人,您也可以在这里传递一个数组:exposedHeaders:[‘授权’,‘X-Total-Count’]
Welcome to SO! Your answer may be correct but at StackOverflow, it is discouraged to post code only answer. Please try to provide an explanation of how your answer solves the original question. please read this on how to Write Better Answer
欢迎来到So!您的答案可能是正确的,但在StackOverflow中,不鼓励发布仅代码答案。请尝试解释一下您的答案是如何解决原始问题的。请阅读这篇关于如何写出更好答案的文章
Thank you for that. I tried the wildcard '*' , which did'nt work, but using your answer as help it really helped me.
谢谢你这么做。我尝试了通配符‘*’,它不起作用,但使用您的答案作为帮助,它真的帮助了我。
At least for Flask CORS, you can also pass a dict where each key is named CORS_<property>
(in this case expose_headers
) and pass it with the desired values in the CORS(app, **cors_config)
statement. See docs here
至少对于FlaskCORS,您还可以传递一个dict,其中每个键都被命名为CORS_(在本例中为expose_Headers),并在CORS(app,**CORS_CONFIG)语句中将其与所需的值一起传递。请参阅此处的文档
我是一名优秀的程序员,十分优秀!