我已经定义了一个http拦截器.在拦截器内部,我有以下代码:

let newReq = req.clone({
  withCredentials: true,
  responseType: 'json'
});

现在,我需要修改所有请求并添加一个值为foo的额外标头Demo

我try 了以下几种方法

let newReq = req.clone({
  withCredentials: true,
  responseType: 'json',
  setHeaders: {'Demo' : 'foo'}
});

但是,我注意到在Network选项卡中,这会从我的请求中删除几乎所有的标头,包括Host&Origin,这会导致与我通信的API出现CORS问题

有什么办法可以解决这个问题吗?(我希望在克隆的请求中保留所有以前的头,然后只添加一个新头)

推荐答案

您的代码似乎工作得很好,并且确实成功地发送了以前的和新的头文件.罪魁祸首是选项withCredentials: true,它导致以下错误:

在‘https://example.com’From Origin‘http://localhost:4200’上访问XMLHttpRequest的权限 已被CORS策略阻止:对印前判断请求的响应不 通过访问控制判断:The value of the 'Access-Control-Allow-Origin' header in the response must not be the wildcard '*' when the request's credentials mode is 'include'.这个 XMLHttpRequest发起的请求的凭据模式为 由with Credentials属性控制.

如错误所示,服务器可能在飞行前判断(OPTIONS请求的响应)中发送标头Access-Control-Allow-Origin: *.只有当服务器发送标头Access-Control-Allow-Origin: http://localhost:4200 (or whatever your origin is)时,您的请求才会起作用.

不能同时使用Access-Control-Allow-Origin: *withCredentials: true的原因解释如下:CORS: Cannot use wildcard in Access-Control-Allow-Origin when credentials flag is true

我创建了一个后端来重现这个问题.执行以下步骤将解决您的问题:

  • http://localhost:4200(或您的原点)添加到允许CORS原点列表(不能将其设置为*).
  • 通过将access-control-allow-headers设置为*,允许将自定义头传递到您的后端.
  • 将CORS设置中的allow_credentials设置为true.

如果您使用的是Python(快速API),则可以这样进行上述设置(已测试并正常工作):

app = FastAPI()

origins = [
    "http://localhost:4200"
]

app.add_middleware(
    CORSMiddleware,
    allow_origins=origins,
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"],
)

如果您使用的是.NET Core,则可以执行以下设置(未经测试):

var MyAllowSpecificOrigins = "_myAllowSpecificOrigins";

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddCors(options =>
{
    options.AddPolicy(MyAllowSpecificOrigins,
                          policy =>
                          {
                              policy.WithOrigins("http://localhost:4200")
                                                  .AllowAnyHeader()
                                                  .AllowAnyMethod()
                                                  .AllowCredentials();
                          });
});

builder.Services.AddControllers();

var app = builder.Build();
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();

app.UseCors(MyAllowSpecificOrigins);

app.UseAuthorization();

app.MapControllers();

app.Run();

也要在IIS上进行类似的设置(如果您使用的是IIS).

  • allowCredentials="true"
  • allowAllRequestedHeaders="true"
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <system.webServer>
        <cors enabled="true" failUnlistedOrigins="true">
            <add origin="http://localhost:4200"
                 allowCredentials="true"
                 maxAge="120"> 
                <allowHeaders allowAllRequestedHeaders="true">
                    <add header="Demo" />
                </allowHeaders>
                <allowMethods>
                     <add method="DELETE" />
                     <add method="GET" />
                     <add method="POST" />
                     <add method="PUT" />
                     <add method="OPTIONS" />
                </allowMethods>
            </add>
        </cors>
    </system.webServer>
</configuration>

Angular相关问答推荐

如何跨不同组件使用ng模板

独立Angular 零部件不在辅零部件或共享零部件中工作

带迭代的Angular 内容投影

如何重新显示ngbAlert(Bootstrap widgest for Angular)消息后再次驳回它

类是一个独立的组件,不能在Angular中的`@NgModule.bootstrap`数组中使用

是否可以在Angular(12+)中迭代指定的范围而不是整个数组

重新打开模态时 ng-select 中的重复值 - Angular

ngrx 效果等到从初始值以外的其他状态收到响应

NgRx Effects 抛出类型错误,我不知道发生了什么

从具有特定 node 值的现有数组创建新数组

Angular APP_INITIALIZER 中的 MSAL 身份验证

PrimeNG:如何以编程方式更改分页器中的选定页面?

Angular:显示带有嵌套子项的内容投影

Error: Module not found: Error: Can't resolve '@angular/cdk/scrolling'

为什么用?模板绑定中的运算符?

无法绑定到 target,因为它不是div的已知属性

如何在 Angular 2 中跟踪路由?

react形式的两种方式绑定

检测图像何时加载到 img 标签中

Error: Can't resolve 'core-js/es7/reflect' in '\node_modules\@angular-devkit\build-angular\src\angular-cli-files\models